Compare commits

...

120 Commits

Author SHA1 Message Date
Konstantinos Triantafyllou 96d5f933f9 Update library before release 2024-04-01 19:03:19 +03:00
Konstantinos Triantafyllou 1b426de160 Merge from develop 2024-04-01 18:32:59 +03:00
Konstantinos Triantafyllou ebd2570985 [develop]: Update library 2024-04-01 18:28:32 +03:00
Konstantinos Triantafyllou 2ba5f7e5fa Update library 2024-04-01 10:59:04 +03:00
Konstantinos Triantafyllou ef7e8ac4d3 Update version before release. 2024-03-28 15:45:40 +02:00
Konstantinos Triantafyllou fcc8cd653d Merge from origin/develop 2024-03-28 13:54:31 +02:00
Konstantinos Triantafyllou 2ac08895b5 Update libraries before deploy 2024-03-28 12:52:21 +02:00
Konstantinos Triantafyllou bdd13890fe [develop]: Fix mixYear and maxYear in range-year filter in monitor component 2024-02-26 09:47:29 +02:00
Konstantinos Triantafyllou db44041bd2 [develop]: Update libraries and remove old properties 2024-02-22 15:13:12 +02:00
Konstantinos Triantafyllou 61a98e851f [develop]: Update libraries and change userInfoUrl from userManagementService. 2024-02-22 10:38:03 +02:00
Konstantinos Triantafyllou f21330e579 Merge pull request 'Merge irish-monitor to develop' (#11) from irish-monitor into develop
Reviewed-on: #11
2024-02-13 10:03:21 +01:00
Konstantinos Triantafyllou 40f694cec9 [irish-monitor]: Fix toggle overlay 2024-02-13 11:02:52 +02:00
Konstantinos Triantafyllou f12adb614f [irish-monitor]: Update libraries before merge to develop 2024-02-13 10:40:32 +02:00
Konstantinos Triantafyllou 2fd44e6d19 [irish-monitor]: Merge from develop 2024-01-24 20:23:37 +02:00
Konstantinos Triantafyllou f3a434ade0 [develop]: Update uikit and remove common properties 2024-01-24 14:37:05 +02:00
Konstantinos Triantafyllou bf1a44ac05 Update library 2024-01-24 14:07:46 +02:00
Konstantinos Triantafyllou e5b1b8da16 [irish-monitor]: Update libraries 2024-01-24 10:38:25 +02:00
Konstantinos Triantafyllou 7d5a5ca899 [develop | FIXED]: Add indicators.less in monitor style. 2024-01-24 09:31:31 +02:00
Konstantina Galouni 72fb9526cf Merge branch 'develop' of code-repo.d4science.org:MaDgIK/monitor-dashboard into develop 2024-01-08 18:10:28 +02:00
Konstantinos Triantafyllou 7f2535543b Merge from develop 2023-12-21 14:52:41 +02:00
Konstantinos Triantafyllou 3ede45600c Change class for indicator-description to indicator overlay and improt it from indicators.less 2023-12-21 14:50:54 +02:00
Alex Martzios 0145245206 [irish-monitor] change the overlay functionality of the indicators based on the new irish-monitors overlay, update submodules 2023-12-18 13:52:18 +02:00
Konstantinos Triantafyllou 8e10efff38 Add copy.js and update libraries 2023-12-12 10:11:05 +02:00
Konstantinos Triantafyllou a94619a46f [develop | DONE]: import indicators.less from common assets 2023-11-16 11:38:06 +02:00
Konstantinos Triantafyllou caa99db227 [irish-monitor | DONE]: App component: use sidebar-base component. Monitor component: use monitor-indicator-stakeholder-base component. 2023-11-14 10:18:29 +02:00
Konstantinos Triantafyllou cf1ea7f2b2 [develop]: Update library 2023-11-13 16:26:38 +02:00
Konstantinos Triantafyllou 6872500d4f Merge develop into master 2023-11-08 14:21:22 +02:00
Konstantinos Triantafyllou 42966b0921 [develop | DONE | FIXED]: Fix private overlay to be avove navbar. 2023-11-07 13:46:10 +02:00
Konstantinos Triantafyllou d0e1006b4d [develop | DONE]: Remove delete properties 2023-11-02 11:34:33 +02:00
Konstantinos Triantafyllou e530869480 [develop | DONE]: Move manage stakeholders to library 2023-11-02 11:31:23 +02:00
Konstantinos Triantafyllou 46696eb500 Update library 2023-10-31 00:09:55 +02:00
Konstantinos Triantafyllou 66856bbb2c Update library 2023-10-30 17:59:10 +02:00
Konstantinos Triantafyllou 8ad033a731 [develop | DONE | CHANGED]: Revert version of UIkit to version 3.16.14 because of parallax. 2023-10-30 17:26:03 +02:00
Konstantinos Triantafyllou db0388e261 Update libraries 2023-10-30 12:08:51 +02:00
Konstantinos Triantafyllou d1a4202577 Merge pull request 'Update to Angular 16' (#7) from angular-16 into develop
Reviewed-on: #7
2023-10-30 11:04:18 +01:00
Konstantinos Triantafyllou 2dceccfb32 [angular-16 | FIXED]: Fix width of main content 2023-10-27 17:32:28 +03:00
Konstantinos Triantafyllou 0be362e646 [angular-16 | DONE | CHANGED]: Make dashboard-sidebar sticky instead of fixed. 2023-10-25 15:16:39 +03:00
Konstantinos Triantafyllou a7f1dd809f Update library after merge with monitor-admin-library 2023-10-24 11:57:53 +03:00
Konstantinos Triantafyllou 3b04e749b5 Merge remote-tracking branch 'origin/monitor-admin-library' into angular-16 2023-10-24 11:56:52 +03:00
Konstantinos Triantafyllou b50411c396 [monitor-admin-library | DONE | CHANGED]: Move general in library 2023-10-20 19:07:56 +03:00
Konstantinos Triantafyllou a3aa803433 Move topics and cache indicators in library. 2023-10-19 16:33:28 +03:00
Konstantinos Triantafyllou 82fb9cb329 Update library before beta deployment 2023-10-16 20:19:22 +03:00
Konstantinos Triantafyllou fc46736f74 Merge remote-tracking branch 'origin/develop' into angular-16 2023-10-13 16:29:30 +03:00
Konstantinos Triantafyllou 803186d407 Update libraries 2023-10-13 16:29:23 +03:00
Konstantina Galouni 1b725e73c4 [Monitor Dashboard | develop]: environments/: Added property swhURL: "https://archive.softwareheritage.org/". 2023-10-10 17:50:32 +03:00
Konstantinos Triantafyllou 1686e017b0 Update types/node to version 16 2023-09-15 11:10:57 +03:00
Konstantinos Triantafyllou 05df84db32 Update library and theme 2023-09-12 18:42:29 +03:00
Konstantinos Triantafyllou e705f1a1cf Convert div - uk-toggle to a - uk-toggle for new Uikit. 2023-09-04 15:15:43 +03:00
Konstantinos Triantafyllou 7d10b2c75b Merge from develop 2023-08-30 16:46:35 +03:00
Konstantinos Triantafyllou 37fe77def6 Add bipFrameAPIURL in properties 2023-08-30 16:44:09 +03:00
Konstantinos Triantafyllou f0cdfccbf4 Update to Uikit 3.16.24 2023-08-22 17:09:41 +03:00
Konstantinos Triantafyllou d1b30f7925 Update library 2023-08-04 15:54:46 +03:00
Konstantinos Triantafyllou bc955c9d15 Update material to angular 16. 2023-08-01 14:33:10 +03:00
Konstantinos Triantafyllou 5bd1ab15ef Update angular to version 16 2023-08-01 14:31:35 +03:00
Konstantinos Triantafyllou 658e92f144 Update Zone to 0.13.1 2023-08-01 13:56:34 +03:00
Konstantinos Triantafyllou f19ecfdfc5 Update material to angular 15. 2023-08-01 13:52:18 +03:00
Konstantinos Triantafyllou 784d0b0e0d Migrate angular core and cli to version 15 and update dependencies to be compatible with the newer version. 2023-08-01 11:02:52 +03:00
Konstantinos Triantafyllou 85ac5ea493 Update typescript to version 4.9.5 2023-08-01 10:48:04 +03:00
Konstantinos Triantafyllou 268eabad50 Update library 2023-08-01 09:48:55 +03:00
Konstantinos Triantafyllou 65dec92864 Update libraries before beta deploy 2023-07-27 16:35:54 +03:00
Konstantinos Triantafyllou 2dd570aa72 Change texts for project update. 2023-07-20 17:04:34 +03:00
Konstantinos Triantafyllou 760adf17c8 Merge branch 'develop' of code-repo.d4science.org:MaDgIK/monitor-dashboard into develop 2023-07-20 13:25:29 +03:00
Konstantinos Triantafyllou eefbeee325 Show project update when a user is loggedin and fix condition if difference of dates is equal to 12 months. 2023-07-20 13:25:18 +03:00
Konstantinos Triantafyllou c39685d841 Update libraries. 2023-07-20 11:51:51 +03:00
Konstantinos Triantafyllou 03fcd9b8ce Add projectUpdate Alert 2023-07-20 11:49:04 +03:00
Konstantinos Triantafyllou d3775ba01f Add projectUpdateDate for curators in edit-stakeholder. 2023-07-19 19:53:23 +03:00
Konstantinos Triantafyllou 4941cf13a1 Update library 2023-07-13 14:46:54 +03:00
Konstantinos Triantafyllou 3f25d9ce66 Disable piwik in dev 2023-07-12 16:27:01 +03:00
Konstantinos Triantafyllou cb6d935171 Change piwik base on the new dynamic piwik. 2023-07-12 16:25:31 +03:00
Konstantinos Triantafyllou 8d6205bb32 Merge remote-tracking branch 'origin/develop' 2023-07-12 13:00:35 +03:00
Konstantinos Triantafyllou f3078b0cdc Update libraries before merge from develop 2023-07-12 12:59:30 +03:00
Konstantinos Triantafyllou dc7a9fc66a Update libraries before deploy 2023-07-12 09:40:03 +03:00
Konstantinos Triantafyllou 83f879f5d3 Merge branch 'develop' of code-repo.d4science.org:MaDgIK/monitor-dashboard into develop 2023-07-10 15:27:09 +03:00
Konstantinos Triantafyllou 558a9fbde2 Import indicators: On save remove null sections. 2023-07-10 15:25:06 +03:00
Konstantina Galouni 47f922ed4e [Monitor Dashboard & Library | develop]: search.module.ts: Set in landing routes data: {hasMenuSearchBar: true} to show search bar in menu. | navigationBar.component.ts: If properties.searchLinkToAll is undefined, navigate to properties.searchLinkToAll from menu search bar. 2023-07-07 10:53:10 +03:00
Konstantinos Triantafyllou b543196a88 Change menu items base on new items in monitor. Add Support in menu of a dashboard. 2023-07-06 13:49:45 +03:00
Konstantinos Triantafyllou f1e959d046 Resources: Open in new tab in dashboards and change URL to monitor. 2023-07-04 14:25:07 +03:00
Konstantinos Triantafyllou 7bed14a825 Revert disable of stats-profile 2023-06-30 15:00:50 +03:00
Konstantinos Triantafyllou 7a4d7637fb update library and theme 2023-06-30 14:59:55 +03:00
Konstantinos Triantafyllou 7aef4d352c Update library 2023-06-30 14:41:03 +03:00
Konstantinos Triantafyllou 10932bb474 Add caching indicators status in stakeholder admin pages with circle progress and percentage. 2023-06-29 13:31:02 +03:00
Konstantinos Triantafyllou db6ddd9c7f Update before deploy 2023-06-28 11:19:37 +03:00
Konstantinos Triantafyllou c95998e8e4 Update library 2023-06-28 11:19:07 +03:00
Konstantinos Triantafyllou 1495cd0f50 Update libraries 2023-06-26 15:26:39 +03:00
Konstantinos Triantafyllou 72a9cb0bc4 Merge from develop 2023-06-16 10:05:35 +03:00
Konstantinos Triantafyllou e594009e17 Merge remote-tracking branch 'origin/develop' 2023-06-16 09:58:33 +03:00
Konstantinos Triantafyllou 56a58c4e81 Update library 2023-06-16 09:49:27 +03:00
Konstantinos Triantafyllou 710a89de3c Merge remote-tracking branch 'origin/develop' into stats-profile 2023-06-09 20:53:36 +03:00
Konstantinos Triantafyllou 9734e24f76 Add locale in edit stakeholder form and use it in number pipes 2023-06-09 20:53:14 +03:00
Konstantinos Triantafyllou f03d5fabec Indicators Utils: Fix getFullUrl replace values. 2023-06-09 13:59:58 +03:00
Konstantinos Triantafyllou 1e23572c16 Disable iframes in developoment, enabled by mistake 2023-06-07 16:33:15 +03:00
Konstantinos Triantafyllou 8713374729 Update library 2023-06-07 14:22:31 +03:00
Konstantinos Triantafyllou 163c668577 Create cache indicators and add methods in server. Remove dashboard path from development. Add button for cache indicators in manage stakeholders 2023-06-07 14:20:48 +03:00
Konstantinos Triantafyllou 1b1fa97574 Merge remote-tracking branch 'origin/develop' 2023-06-01 14:35:12 +03:00
Konstantinos Triantafyllou 0696dffa16 Update library after merge from develop to master 2023-06-01 14:33:59 +03:00
Konstantinos Triantafyllou 8e6161087b Update library and theme 2023-06-01 14:32:41 +03:00
Konstantinos Triantafyllou ca390ca71b Update library 2023-06-01 14:02:31 +03:00
Konstantinos Triantafyllou 2e3465ae45 [WIP]: Move indicator sources in IndicatorUtils. Add stats-tool-parser in order to parse json from indicators and convert it to POST request. Add axios library. 2023-06-01 13:58:43 +03:00
Konstantinos Triantafyllou a30c492ffb On create default stakeholder: add choose template in order to initialize from other default profile. 2023-05-30 15:26:52 +03:00
Konstantinos Triantafyllou ab13a41625 Merge from develop 2023-05-29 15:26:29 +03:00
Konstantinos Triantafyllou 14c2ca005d Update library and themme. Fix name in logoInfo (was index_name) 2023-05-25 10:03:21 +03:00
Konstantinos Triantafyllou 4b1b55187d Add stakeholder name in logo info section of header. 2023-05-24 19:00:19 +03:00
Konstantinos Triantafyllou 4e313409cd Resolved Monitor Dashboard release 16th May 2023 #4 2023-05-16 17:42:06 +03:00
Konstantinos Triantafyllou 85d3119efe Merge develop into stats-profile 2023-05-16 13:27:46 +03:00
Konstantinos Triantafyllou 68bd4a9b3c Update library 2023-05-16 13:25:17 +03:00
Konstantinos Triantafyllou c4c3e9841b Rename OpenAIRE Research Graph into OpenAIRE Graph and add the new logo in powered by sections. 2023-05-15 17:05:33 +03:00
Konstantinos Triantafyllou 8bc41b6c70 Merge from pull request Update before Production May Release #3 2023-05-09 13:20:51 +03:00
Konstantinos Triantafyllou 7fe7be599f Update library before deploy 2023-05-09 11:30:45 +03:00
Konstantinos Triantafyllou faa5bca9c1 Merge from develop 2023-05-05 17:08:54 +03:00
Konstantinos Triantafyllou c7c1631ca8 Update library 2023-05-05 17:05:59 +03:00
Konstantinos Triantafyllou 3acd04e4f8 Update library 2023-05-03 16:30:45 +03:00
Konstantinos Triantafyllou fde7351cf3 Update library 2023-05-02 18:09:53 +03:00
Konstantinos Triantafyllou 6ac18841f0 Merge from develop 2023-04-27 16:29:12 +03:00
Konstantinos Triantafyllou 0a673c84a5 Merge from develop 2023-04-26 12:28:17 +03:00
Konstantinos Triantafyllou a63ff6d785 Delete stats profile page. Change get stats profiles endpoint to stats tool. 2023-04-25 15:21:55 +03:00
Konstantinos Triantafyllou 40c68f8f08 Merge from develop 2023-04-24 12:46:14 +03:00
Konstantinos Triantafyllou 54fa0aa7a6 Add format in number indicators in order to support percentages. 2023-04-18 15:30:05 +03:00
Konstantinos Triantafyllou be7fd26f7b Add stasProfile input in edit-stakeholder and replace its value in all indicators URL. 2023-04-12 17:59:57 +03:00
Konstantinos Triantafyllou 9a5de31d58 Add notification on save of stats-profile. 2023-04-11 14:01:14 +03:00
Konstantinos Triantafyllou 7b59267582 Create stats profile admin page 2023-04-11 01:29:30 +03:00
66 changed files with 407 additions and 6632 deletions

View File

@ -48,6 +48,7 @@
"src/assets/common-assets/library-css/material.scss"
],
"scripts": [
"src/assets/common-assets/js/copy.js",
"node_modules/uikit/dist/js/uikit.min.js",
"node_modules/uikit/dist/js/uikit-icons.min.js",
"node_modules/jquery/dist/jquery.js"
@ -208,13 +209,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
"optimization": true,
"vendorChunk": true,
"buildOptimizer": true
},
"beta": {
"outputHashing": "media",
@ -225,7 +229,8 @@
}
],
"sourceMap": false,
"optimization": true
"optimization": true,
"buildOptimizer": true
},
"production": {
"outputHashing": "media",
@ -236,7 +241,8 @@
}
],
"sourceMap": false,
"optimization": true
"optimization": true,
"buildOptimizer": true
}
},
"defaultConfiguration": ""

View File

@ -1,17 +1,17 @@
{
"name": "monitor-dashboard",
"version": "1.0.0",
"version": "1.0.1",
"scripts": {
"ng": "ng",
"start": "ng serve --port 4600 --disable-host-check --host 0.0.0.0",
"build": "ng build",
"build-dev": "ng build --configuration=development --source-map --base-href /dashboard/",
"build-dev": "ng build --configuration=development --source-map",
"build-beta": "ng build --configuration=beta --base-href /dashboard/ --source-map",
"build-prod": "ng build --configuration production --base-href /dashboard/ --source-map",
"webpack-bundle-analyzer": "ng build --stats-json && webpack-bundle-analyzer dist/monitor-dashboard/browser/stats.json --host 0.0.0.0",
"test": "ng test",
"e2e": "ng e2e",
"dev:ssr": "ng run monitor-dashboard:serve-ssr",
"dev:ssr": "ng run monitor-dashboard:serve-ssr --port 4600",
"serve:ssr": "node dist/monitor-dashboard/server/main.js",
"build:ssr-dev": "npm run build-dev && ng run monitor-dashboard:server:development",
"build:ssr-beta": "npm run build-beta && ng run monitor-dashboard:server:beta",
@ -21,43 +21,44 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^14.2.3",
"@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/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/animations": "^16.1.7",
"@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": "^16.1.6",
"@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": "^10.0.0",
"ng-recaptcha": "^12.0.2",
"ng2-ckeditor": "1.3.7",
"rxjs": "^6.5.1",
"ts-md5": "^1.2.0",
"tslib": "^2.0.0",
"uikit": "3.13.10",
"zone.js": "~0.11.4"
"uikit": "3.16.24",
"zone.js": "~0.13.1"
},
"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": "^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",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"@types/ckeditor": "^4.9.10",
"@types/node": "^16.18.50",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.8.0",
"jasmine-spec-reporter": "~5.0.0",
@ -68,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"
}
}

View File

@ -1,14 +1,23 @@
import 'zone.js/node';
import { ngExpressEngine } from '@nguniversal/express-engine';
import {ngExpressEngine} from '@nguniversal/express-engine';
import * as express from 'express';
import * as compression from 'compression';
import { join } from 'path';
import {join} from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';
import {AppServerModule} from './src/main.server';
import {APP_BASE_HREF} from '@angular/common';
import {existsSync} from 'fs';
import {REQUEST, RESPONSE} from "./src/app/openaireLibrary/utils/tokens";
import {properties} from "./src/environments/environment";
import axios, {AxiosHeaders} from "axios";
import {Stakeholder} from "./src/app/openaireLibrary/monitor/entities/stakeholder";
import {CacheIndicators} from "./src/app/openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators";
import {Session, User} from "./src/app/openaireLibrary/login/utils/helper.class";
import {UserManagementService} from "./src/app/openaireLibrary/services/user-management.service";
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json();
// The Express app is exported so that it can be used by serverless Functions.
export function app() {
@ -16,23 +25,90 @@ export function app() {
server.use(compression());
const distFolder = join(process.cwd(), 'dist/monitor-dashboard/browser');
const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';
let cacheIndicators: CacheIndicators = new CacheIndicators();
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
server.engine('html', ngExpressEngine({
bootstrap: AppServerModule,
inlineCriticalCss: false
}));
server.set('view engine', 'html');
server.set('views', distFolder);
server.use('/cache', function (req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS, POST, DELETE');
res.header('Access-Control-Max-Age', "1800");
next();
});
server.post('/cache/:alias', jsonParser, async (req, res) => {
await checkPermissions(req, res, (stakeholder, user) => {
if (cacheIndicators.completed(stakeholder._id)) {
res.send({
id: stakeholder._id,
report: cacheIndicators.createReport(stakeholder._id, cacheIndicators.stakeholderToCacheItems(stakeholder), stakeholder.name, user.email)
});
} else {
res.status(409).send('There is another active caching process for this stakeholder');
}
});
});
server.get('/cache/:alias', async (req, res) => {
await checkPermissions(req, res, stakeholder => {
if (cacheIndicators.exists(stakeholder._id)) {
res.send({
id: stakeholder._id,
report: cacheIndicators.getReport(stakeholder._id)
});
} else {
res.status(404).send('There is not an active caching process for this stakeholder');
}
});
});
async function checkPermissions(req, res, access: (stakeholder, user) => void) {
let headers: AxiosHeaders = new AxiosHeaders();
headers.set('Cookie', req.headers.cookie);
let userinfoRes = (await axios.get<any>(UserManagementService.userInfoUrl(), {
withCredentials: true,
headers: headers
}).catch(error => {
return error.response;
}));
if (userinfoRes.status === 200) {
let user = new User(userinfoRes.data);
let stakeholderRes = (await axios.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(req.params.alias), {
withCredentials: true,
headers: headers
}).catch(error => {
return error.response;
}));
if (stakeholderRes.status === 200) {
let stakeholder = stakeholderRes.data;
if (Session.isPortalAdministrator(user) || Session.isCurator(stakeholder.type, user)) {
access(stakeholder, user);
} else {
res.status(403).send('You are forbidden to access this resource');
}
} else {
res.status(stakeholderRes.status).send(stakeholderRes.statusText);
}
} else {
res.status(userinfoRes.status).send(userinfoRes.data.message);
}
}
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get('*.*', express.static(distFolder, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
server.get('*', (req, res) => {
res.render(indexHtml, {
@ -51,13 +127,13 @@ export function app() {
}
);
});
return server;
}
function run() {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {

View File

@ -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'
},
{
@ -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'
},

View File

@ -2,8 +2,8 @@ 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 = [
{
@ -23,7 +23,7 @@ const routes: Routes = [
},
{
path: 'admin',
loadChildren: () => import('./manageStakeholders/manageStakeholders.module').then(m => m.ManageStakeholdersModule),
loadChildren: () => import('./openaireLibrary/monitor-admin/manageStakeholders/manageStakeholders.module').then(m => m.ManageStakeholdersModule),
canActivateChild: [LoginGuard],
data: {hasAdminMenu: true, hasSidebar: false}
},

View File

@ -2,26 +2,45 @@
<loading [full]="true"></loading>
</div>
<div *ngIf="!loading" [class.monitor]="isFrontPage">
<div class="sidebar_main_swipe uk-background-default" [class.sidebar_main_active]="open && (hasSidebar || hasAdminMenu || hasInternalSidebar)"
[class.sidebar_mini]="!open && (hasSidebar || hasAdminMenu || hasInternalSidebar)" [class.sidebar_hover]="hover">
<div id="modal-container"></div>
<ng-container *ngIf="!isHidden">
<navbar *ngIf="hasHeader" portal="monitor_dashboard" [header]="menuHeader" [userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user"
[notificationConfiguration]="isMobile && user && notificationGroupsInitialized?notificationConfiguration:null"></navbar>
<div>
<dashboard-sidebar *ngIf="stakeholder && isFrontPage && hasSidebar && !hasInternalSidebar" queryParamsHandling="merge" [items]="sideBarItems"
[activeItem]="activeTopic?activeTopic.alias:null" [activeSubItem]="activeCategory?activeCategory.alias:null"></dashboard-sidebar>
<dashboard-sidebar *ngIf="hasAdminMenu && !hasInternalSidebar" [items]="adminMenuItems" [backItem]="backItem"></dashboard-sidebar>
<main>
<router-outlet></router-outlet>
</main>
<div id="modal-container"></div>
<ng-container *ngIf="!isHidden">
<navbar *ngIf="hasHeader" portal="monitor_dashboard" [header]="menuHeader" [userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user"
[notificationConfiguration]="isMobile && user && notificationGroupsInitialized?notificationConfiguration:null"></navbar>
<div>
<div class="sidebar_main_swipe uk-flex uk-background-default" [class.sidebar_main_active]="open && (hasSidebar || hasAdminMenu || hasInternalSidebar)"
[class.sidebar_mini]="!open && (hasSidebar || hasAdminMenu || hasInternalSidebar)" [class.sidebar_hover]="hover">
<dashboard-sidebar *ngIf="stakeholder && isFrontPage && hasSidebar && !hasInternalSidebar" queryParamsHandling="merge" [items]="sideBarItems"
[activeItem]="activeTopic?activeTopic.alias:null" [activeSubItem]="activeCategory?activeCategory.alias:null"></dashboard-sidebar>
<dashboard-sidebar *ngIf="hasAdminMenu && !hasInternalSidebar" [items]="adminMenuItems" [backItem]="backItem"></dashboard-sidebar>
<main class="uk-width-1-1">
<router-outlet></router-outlet>
</main>
</div>
<bottom id="bottom" *ngIf="isFrontPage" [centered]="true" [properties]="properties" [showMenuItems]="true"></bottom>
<notification-sidebar *ngIf="!isMobile && user && notificationGroupsInitialized" [configuration]="notificationConfiguration" [user]="user"></notification-sidebar>
<cache-indicators *ngIf="stakeholder && !isFrontPage && isCurator()" [alias]="stakeholder.alias"></cache-indicators>
<div *ngIf="view" class="preview uk-text-small uk-flex uk-flex-middle">
<span>You are currently in a <span class="uk-text-bold">"Preview"</span> mode. <span class="uk-visible@m"><a (click)="removeView()">The current view</a> of this dashboard may differ.</span></span>
</div>
</div>
</ng-container>
<div *ngIf="projectUpdate && !isFrontPage" class="project-update">
<div *ngIf="projectUpdate === 'danger'" class="uk-alert uk-alert-danger" uk-alert>
<a class="uk-alert-close" uk-close></a>
<div class="uk-text-bold uk-text-small">Projects Status: Urgent Update Needed</div>
<div class="uk-margin-xsmall-top uk-text-xsmall">
Your project list was last updated more than a year ago. Please send an updated project list to
<a href="mailto:mining@openaire.eu">mining@openaire.eu</a> or contact <a [href]="monitorLink + '/contact-us'">support</a>.
</div>
<div *ngIf="view" class="preview uk-text-small uk-flex uk-flex-middle">
<span>You are currently in a <span class="uk-text-bold">"Preview"</span> mode. <span class="uk-visible@m"><a (click)="removeView()">The current view</a> of this dashboard may differ.</span></span>
</div>
<div *ngIf="projectUpdate === 'warning'" class="uk-alert uk-alert-warning" uk-alert>
<a class="uk-alert-close" uk-close></a>
<div class="uk-text-bold uk-text-small">Projects Status: Update Needed</div>
<div class="uk-margin-xsmall-top uk-text-xsmall">
Your project list was last updated between 6 to 12 months ago. Please send an updated project list to
<a href="mailto:mining@openaire.eu">mining@openaire.eu</a> or contact <a [href]="monitorLink + '/contact-us'" target="_blank" class="custom-external">support</a>.
</div>
</ng-container>
</div>
</div>
<div *ngIf="isHidden" class="private-data uk-light dark">
<div class="uk-section uk-section-small uk-container uk-container-small uk-text-center">

View File

@ -0,0 +1,12 @@
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
.project-update {
z-index: @global-z-index;
position: fixed;
bottom: 0;
left: 50%;
right: 50%;
transform: translate(-50%, 0);
width: 500px;
max-width: 60%;
}

View File

@ -1,4 +1,4 @@
import {ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit} from '@angular/core';
import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, Data, NavigationEnd, Params, Router} from '@angular/router';
import {EnvProperties} from './openaireLibrary/utils/properties/env-properties';
import {Role, Session, User} from './openaireLibrary/login/utils/helper.class';
@ -18,8 +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 {Option} from "./openaireLibrary/sharedComponents/input/input.component";
import {StakeholderUtils} from "./utils/indicator-utils";
import {StakeholderConfiguration, 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";
@ -27,18 +26,18 @@ import {StringUtils} from "./openaireLibrary/utils/string-utils.class";
import {
NotificationConfiguration
} from "./openaireLibrary/notifications/notifications-sidebar/notifications-sidebar.component";
import {StakeholderBaseComponent} from "./openaireLibrary/monitor-admin/utils/stakeholder-base.component";
import {SidebarBaseComponent} from "./openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-base.component";
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
templateUrl: './app.component.html',
styleUrls: ['app.component.less']
})
export class AppComponent implements OnInit, OnDestroy {
properties: EnvProperties = properties;
export class AppComponent extends SidebarBaseComponent implements OnInit {
user: User;
updateStakeholder: boolean = true;
params: BehaviorSubject<Params> = new BehaviorSubject<Params>(null);
data: BehaviorSubject<Data> = new BehaviorSubject<Data>(null);
hasSidebar: boolean = false;
hasHeader: boolean = false;
hasAdminMenu: boolean = false;
@ -46,13 +45,10 @@ export class AppComponent implements OnInit, OnDestroy {
isFrontPage: boolean = false;
isMobile: boolean = false;
view: Visibility;
sideBarItems: MenuItem[] = [];
backItem: MenuItem = null;
menuItems: MenuItem[] = [];
notificationGroupsInitialized: boolean = false;
notificationConfiguration: NotificationConfiguration = new NotificationConfiguration();
stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public stakeholderEntities = StakeholderEntities;
menuHeader: Header = {
route: "/",
url: null,
@ -63,7 +59,6 @@ export class AppComponent implements OnInit, OnDestroy {
badge: true,
menuPosition: "center"
};
userMenuItems: MenuItem[] = [];
adminMenuItems: MenuItem[] = [];
stakeholder: Stakeholder = null;
@ -72,39 +67,27 @@ export class AppComponent implements OnInit, OnDestroy {
loading: boolean = true;
paramsResolved: boolean = false;
innerWidth;
projectUpdate: 'danger' | 'warning';
paramsSubscription: Subscription;
private subscriptions: any[] = [];
constructor(private route: ActivatedRoute,
private router: Router,
constructor(protected _route: ActivatedRoute,
protected _router: Router,
protected layoutService: LayoutService,
protected cdr: ChangeDetectorRef,
private userManagementService: UserManagementService,
private layoutService: LayoutService,
private smoothScroll: SmoothScroll,
private stakeholderService: StakeholderService,
private cdr: ChangeDetectorRef,
private configurationService: ConfigurationService,
private resourcesService: ResourcesService) {
this.subscriptions.push(this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
let r = this.route;
while (r.firstChild) {
r = r.firstChild;
}
this.paramsResolved = true;
this.params.next(r.snapshot.params);
this.data.next(r.snapshot.data);
}
}));
super();
this.initRouterParams(_route);
}
ngOnInit() {
super.ngOnInit();
if (typeof document !== 'undefined' && window) {
this.innerWidth = window.innerWidth;
}
this.subscriptions.push(this.layoutService.hasSidebar.subscribe(hasSidebar => {
this.hasSidebar = hasSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasHeader.subscribe(hasHeader => {
this.hasHeader = hasHeader;
this.cdr.detectChanges();
@ -113,10 +96,6 @@ export class AppComponent implements OnInit, OnDestroy {
this.hasAdminMenu = hasAdminMenu;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasInternalSidebar.subscribe(hasInternalSidebar => {
this.hasInternalSidebar = hasInternalSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.isFrontPage.subscribe(isFrontPage => {
this.isFrontPage = isFrontPage;
this.cdr.detectChanges();
@ -125,21 +104,20 @@ export class AppComponent implements OnInit, OnDestroy {
this.isMobile = isMobile;
this.cdr.detectChanges();
}));
this.route.queryParams.subscribe(params => {
this._route.queryParams.subscribe(params => {
this.view = params['view'];
if(this.stakeholder) {
this.setSideBar();
}
});
this.layoutService.setOpen(true);
this.subscriptions.push(this.data.subscribe(data => {
if (data && data.portal) {
this.setProperties(data.portal);
this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity);
this.configurationService.initPortal(this.properties, this.properties.adminToolsCommunity);
}
}));
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.updateStakeholder = !this.router.url.includes('user-info');
this.updateStakeholder = !this._router.url.includes('user-info');
if (user) {
this.user = user;
if (!this.notificationGroupsInitialized) {
@ -190,6 +168,9 @@ export class AppComponent implements OnInit, OnDestroy {
}
}
});
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.setProjectUpdate(stakeholder);
}))
}));
}
@ -236,16 +217,29 @@ export class AppComponent implements OnInit, OnDestroy {
this.notificationGroupsInitialized = true;
}));
}
public setProjectUpdate(stakeholder: Stakeholder) {
if(stakeholder?.projectUpdateDate && this.user) {
let today = new Date();
let date = new Date(stakeholder.projectUpdateDate);
let months = (today.getFullYear() - date.getFullYear())*12 + (today.getMonth() - date.getMonth());
if(months >= 12) {
this.projectUpdate = 'danger';
} else if (months >= 6 && months < 12) {
this.projectUpdate = 'warning';
} else {
this.projectUpdate = null;
}
} else {
this.projectUpdate = null;
}
}
public ngOnDestroy() {
super.ngOnDestroy();
if(this.paramsSubscription) {
this.paramsSubscription.unsubscribe();
}
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
this.userManagementService.clearSubscriptions();
this.layoutService.clearSubscriptions();
this.stakeholderService.clearSubscriptions();
@ -254,25 +248,17 @@ export class AppComponent implements OnInit, OnDestroy {
}
private navigateToError() {
this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.properties.baseLink + this.router.url}});
this._router.navigate([this.properties.errorLink], {queryParams: {'page': this.properties.baseLink + this._router.url}});
}
public removeView() {
this.router.navigate([], {relativeTo: this.route});
this._router.navigate([], {relativeTo: this._route});
}
public login() {
this.userManagementService.login();
}
public get open() {
return this.layoutService.open;
}
public get hover() {
return this.layoutService.hover;
}
get isHidden() {
return this.stakeholder && !this.hasPermission(this.view?this.view:this.stakeholder.visibility);
}
@ -343,7 +329,8 @@ export class AppComponent implements OnInit, OnDestroy {
false, [], null, {resultbestaccessright: '"' + encodeURIComponent("Open Access") + '"'},
null, null, null, null)
);
this.resourcesService.setResources(this.menuItems, "/" + this.stakeholder.alias);
this.resourcesService.setResources(this.menuItems, '', this.monitorLink, '_blank');
this.menuItems.push(new MenuItem("support", "Support", this.monitorLink + '/support/', "", false, [], null, {}));
if (this.stakeholder.type === "funder") {
this.menuItems.push(
new MenuItem("develop", "Develop",
@ -365,8 +352,8 @@ export class AppComponent implements OnInit, OnDestroy {
title: this.stakeholder.name,
logoUrl: StringUtils.getLogoUrl(this.stakeholder),
logoSmallUrl: StringUtils.getLogoUrl(this.stakeholder),
logoInfo: '<div class="uk-margin-left uk-width-medium"><div class="uk-margin-remove uk-text-background uk-text-bold uk-text-small">Monitor</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">Dashboard</div></div>',
logoInfo: '<div class="uk-margin-left uk-width-medium"><div class="uk-margin-remove uk-text-background uk-text-bold uk-text-small">Monitor Dashboard</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">' + this.stakeholder.name + '</div></div>',
position: 'left',
badge: true,
menuPosition: "center"
@ -378,8 +365,8 @@ export class AppComponent implements OnInit, OnDestroy {
title: this.stakeholder.name,
logoUrl: StringUtils.getLogoUrl(this.stakeholder),
logoSmallUrl: StringUtils.getLogoUrl(this.stakeholder),
logoInfo: '<div class="uk-margin-left uk-width-medium"><div class="uk-margin-remove uk-text-background uk-text-bold uk-text-small">Monitor Admin</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">Dashboard</div></div>',
logoInfo: '<div class="uk-margin-left uk-width-medium"><div class="uk-margin-remove uk-text-background uk-text-bold uk-text-small">Monitor Admin Dashboard</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">' + this.stakeholder.name + '</div></div>',
position: 'left',
badge: true,
menuPosition: "center"
@ -398,16 +385,12 @@ export class AppComponent implements OnInit, OnDestroy {
menuPosition: "center"
};
this.menuItems.push(
new MenuItem("stakeholders", "Browse " + this.stakeholderEntities.STAKEHOLDERS,
new MenuItem("stakeholders", "Browse " + this.stakeholderUtils.entities.stakeholders,
this.monitorLink + '/browse', "", false, [], null, {}, null, null, null, null, "_self")
);
this.resourcesService.setResources(this.menuItems, '', this.monitorLink);
let about = new MenuItem("about", "About", "", "", false, [], null, {});
about.items = [
new MenuItem("how-it-works", "How it works", this.monitorLink + '/about/how-it-works', "", false, [], null, {}, null, null, null, null, "_self"),
new MenuItem("faqs", "FAQs", this.monitorLink + '/about/faqs',"", false, [], null, {}, null, null, null, null, "_self")
]
this.menuItems.push(about);
this.menuItems.push(new MenuItem("support", "Support", this.monitorLink + '/support/', "", false, [], null, {}, null, null, null, null, "_self"));
this.menuItems.push(new MenuItem("about", "About", this.monitorLink + '/about/', "", false, [], null, {}, null, null, null, null, "_self"));
if (this.hasAdminMenu) {
this.adminMenuItems = [];
this.backItem = null;
@ -457,6 +440,6 @@ export class AppComponent implements OnInit, OnDestroy {
} else {
ConnectHelper.setPortalTypeFromPid(id);
}
this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity);
this.configurationService.initPortal(this.properties, this.properties.adminToolsCommunity);
}
}

View File

@ -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";
@ -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,9 +28,11 @@ 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 {AdminDashboardGuard} from "./openaireLibrary/monitor-admin/utils/adminDashboard.guard";
import {CacheIndicatorsModule} from "./openaireLibrary/monitor-admin/utils/cache-indicators/cache-indicators.module";
@NgModule({
imports: [
SharedModule,
BrowserAnimationsModule,
@ -42,13 +43,14 @@ import {incognito} from "./openaireLibrary/utils/icons/icons";
NavigationBarModule,
BottomModule,
CookieLawModule,
BrowserModule.withServerTransition({appId: 'serverApp'}),
BrowserModule,
AppRoutingModule,
SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule, IconsModule
SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule, IconsModule, CacheIndicatorsModule
],
declarations: [AppComponent, OpenaireErrorPageComponent],
exports: [AppComponent],
providers: [
{provide: APP_ID, useValue: 'monitor-dashboard'},
AdminLoginGuard, AdminDashboardGuard, LoginGuard,
{
provide: HTTP_INTERCEPTORS,

View File

@ -6,9 +6,10 @@ 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";
@Component({
selector: 'develop',
@ -132,6 +133,7 @@ export class DevelopComponent implements OnInit, OnDestroy {
constructor(private stakeholderService: StakeholderService,
private seoService: SEOService,
private _meta: Meta,
private piwikService: PiwikService,
private _router: Router,
private _title: Title) {
}
@ -153,7 +155,7 @@ export class DevelopComponent implements OnInit, OnDestroy {
this._meta.updateTag({content: description}, "property='og:description'");
this._meta.updateTag({content: title}, "property='og:title'");
this._title.setTitle(title);
this.subscriptions.push(this.piwikService.trackView(properties, title).subscribe());
/* Initializations */
this.stakeholderUtils.types.forEach(type => {
if (type.value === stakeholder.type) {

View File

@ -1,10 +0,0 @@
.uk-border-circle {
width: 100px;
height: 100px;
position: relative;
& > img {
max-width: 64px;
max-height: 64px;
}
}

View File

@ -1,401 +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 "../../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";
@Component({
selector: 'edit-stakeholder',
template: `
<form *ngIf="stakeholderFb" [formGroup]="stakeholderFb">
<div class="uk-grid uk-grid-large" uk-grid>
<div class="uk-width-1-2@m">
<div input id="name" [formInput]="stakeholderFb.get('name')"
placeholder="Name"></div>
</div>
<div class="uk-width-1-2@m">
<div input [formInput]="stakeholderFb.get('alias')"
placeholder="URL Alias"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_id')"
placeholder="Index ID"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_name')"
placeholder="Index Name"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_shortName')"
placeholder="Index Short Name"></div>
</div>
<div class="uk-width-1-1">
<div input [type]="'textarea'" placeholder="Description"
[rows]="4" [formInput]="stakeholderFb.get('description')"></div>
</div>
<div class="uk-width-1-1">
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
<div *ngIf="!stakeholderFb.get('isUpload').value" class="uk-grid uk-grid-column-large" uk-grid>
<div class="uk-margin-top uk-width-auto@l uk-width-1-1">
<div class="uk-grid uk-grid-column-large uk-flex-middle" uk-grid>
<div class="uk-width-auto@l uk-width-1-1 uk-flex uk-flex-center">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle uk-flex-wrap"
(click)="file.click()">
<icon name="cloud_upload" [flex]="true"></icon>
<span class="uk-margin-small-left">Upload a file</span>
</button>
</div>
<div class="uk-text-center uk-text-bold uk-width-expand">
OR
</div>
</div>
</div>
<div input class="uk-width-expand" type="logoURL" [placeholder]="'Link to the logo'" [formInput]="stakeholderFb.get('logoUrl')"></div>
</div>
<div *ngIf="stakeholderFb.get('isUpload').value" class="uk-width-1-1 uk-flex uk-flex-middle">
<div class="uk-card uk-card-default uk-text-center uk-border-circle">
<img class="uk-position-center uk-blend-multiply" [src]="photo">
</div>
<div class="uk-margin-left">
<button (click)="remove()" class="uk-button-danger uk-icon-button uk-icon-button-small">
<icon [flex]="true" ratio="0.8" name="delete"></icon>
</button>
</div>
<div class="uk-margin-small-left">
<button class="uk-button-secondary uk-icon-button uk-icon-button-small" (click)="file.click()">
<icon [flex]="true" ratio="0.8" name="edit"></icon>
</button>
</div>
</div>
<!-- Full width error message -->
<div *ngIf="uploadError" class="uk-text-danger uk-margin-small-top uk-width-1-1">{{uploadError}}</div>
</div>
<div [class]="canChooseType ? 'uk-width-1-3@m' : 'uk-width-1-2@m'">
<div input [formInput]="stakeholderFb.get('visibility')"
[placeholder]="'Select a status'"
[options]="stakeholderUtils.statuses" type="select"></div>
</div>
<div [class]="canChooseType ? 'uk-width-1-3@m' : 'uk-width-1-2@m'">
<div input [formInput]="stakeholderFb.get('type')"
[placeholder]="'Select a type'"
[options]="types" type="select"></div>
</div>
<ng-container *ngIf="canChooseType">
<div class="uk-width-1-3@m">
<div [placeholder]="'Select a template'"
input [formInput]="stakeholderFb.get('defaultId')"
[options]="defaultStakeholdersOptions" type="select"></div>
</div>
</ng-container>
</div>
</form>
<div #notify [class.uk-hidden]="!stakeholderFb" notify-form class="uk-width-1-1 uk-margin-large-top uk-margin-medium-bottom"></div>
`,
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 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 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;
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),
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();
if (!isDefault) {
this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => {
this.onTypeChange(value, defaultStakeholders);
}));
this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, Validators.required));
}
if (!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 {
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 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 canChooseType(): boolean {
return !this.stakeholderFb.get('isDefault').value && 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, 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) {
if (!this.stakeholderFb.getRawValue().isDefault) {
let stakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId);
this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(),
(stakeholder ? stakeholder.topics : [])));
}
this.removePhoto();
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 <b>successfully created</b>');
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 <b>successfully saved</b>');
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') {
(<HTMLInputElement>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());
}
}
}

View File

@ -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 {}

View File

@ -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 {
}

View File

@ -1,29 +0,0 @@
<div page-content>
<div actions>
<sidebar-mobile-toggle class="uk-margin-top uk-hidden@m uk-display-block"></sidebar-mobile-toggle>
<div class="uk-section-xsmall uk-container uk-margin-top">
<div class="uk-flex uk-flex-center uk-flex-right@m">
<button class="uk-button uk-button-default uk-margin-right"
(click)="reset()" [class.uk-disabled]="loading || !editStakeholderComponent.dirty"
[disabled]="loading || !editStakeholderComponent.dirty">Reset
</button>
<button class="uk-button uk-button-primary" [class.uk-disabled]="loading || editStakeholderComponent.disabled"
(click)="save()" [disabled]="loading || editStakeholderComponent.disabled">Save
</button>
</div>
</div>
</div>
<div inner>
<div *ngIf="stakeholder" class="uk-container">
<div class="uk-position-relative" style="min-height: 60vh">
<div [class.uk-hidden]="loading" class="uk-section uk-section-small">
<edit-stakeholder #editStakeholderComponent [disableAlias]="true"></edit-stakeholder>
</div>
<div *ngIf="loading" class="uk-position-center">
<loading *ngIf="loading"></loading>
</div>
</div>
</div>
</div>
</div>

View File

@ -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();
}
});
}
}

View File

@ -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 {
}

View File

@ -1,18 +0,0 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard';
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: ManageStakeholdersComponent,
canDeactivate: [PreviousRouteRecorder]
}
])
]
})
export class ManageStakeholdersRoutingModule {
}

View File

@ -1,135 +0,0 @@
<div page-content>
<div header>
<sidebar-mobile-toggle class="uk-margin-top uk-hidden@m uk-display-block"></sidebar-mobile-toggle>
<div *ngIf="isCurator()" class="uk-margin-remove-bottom uk-margin-medium-top">
<slider-tabs [type]="'dynamic'" (activeEmitter)="tab = $event">
<slider-tab tabTitle="All" [tabId]="'all'" [active]="tab === 'all'"></slider-tab>
<slider-tab tabTitle="Profile templates" [tabId]="'templates'" [active]="tab === 'templates'"></slider-tab>
<slider-tab tabTitle="Profiles" [tabId]="'profiles'" [active]="tab === 'profiles'"></slider-tab>
</slider-tabs>
</div>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle">
<div search-input [searchControl]="filters.get('keyword')" [expandable]="true" placeholder="Search Profiles" searchInputClass="outer"
class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div>
</div>
</div>
</div>
<div inner>
<div *ngIf="loading" class="uk-margin-medium-top uk-padding-large">
<loading></loading>
</div>
<div *ngIf="!loading" uk-height-match="target: .titleContainer; row: false">
<div uk-height-match="target: .logoContainer; row: false">
<div *ngIf="tab != 'profiles' && isCurator()" class="uk-section">
<h4>Profile Templates</h4>
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1 uk-grid-match" uk-grid>
<ng-template ngFor [ngForOf]="displayDefaultStakeholders" let-stakeholder>
<ng-container *ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
</ng-template>
<div *ngIf="!loading && isCurator()">
<ng-container *ngTemplateOutlet="newBox; context: {text:'Create a new default profile.', isDefault:true}"></ng-container>
</div>
</div>
</div>
<div *ngIf="!isManager()" class="message">
<h4 class="uk-text-center">
No profiles to manage yet
</h4>
</div>
<div *ngIf="tab != 'templates' && isManager()" class="uk-section">
<h4>Profiles</h4>
<div class="uk-grid uk-grid-match uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1" uk-grid>
<ng-template ngFor [ngForOf]="displayStakeholders" let-stakeholder>
<ng-container *ngTemplateOutlet="stakeholderBox; context: {stakeholder:stakeholder}"></ng-container>
</ng-template>
<div *ngIf="!loading && isCurator()">
<ng-container *ngTemplateOutlet="newBox; context: {text:'Create a new profile by selecting the type ('+stakeholderEntities.FUNDER+', '+stakeholderEntities.ORGANIZATION+', '+stakeholderEntities.RI+' or '+stakeholderEntities.PROJECT+') and ' +
'select indicators based on a default or a blank profile.', isDefault:false}"></ng-container>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<ng-template #stakeholderBox let-stakeholder="stakeholder">
<div *ngIf="stakeholder">
<div class="uk-card uk-card-default uk-card-body uk-position-relative" [ngClass]="stakeholder.type">
<div class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0;">
<ul class="uk-nav uk-dropdown-nav">
<li>
<a (click)="editStakeholder(stakeholder, !stakeholder.defaultId); hide(element)">Edit</a>
</li>
<li class="uk-nav-divider"></li>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="stakeholder.visibility === v.value">
<a (click)="changeStakeholderStatus(stakeholder, v.value);hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="stakeholder.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<hr *ngIf="isProfileManager(stakeholder)" class="uk-nav-divider">
<li *ngIf="isProfileManager(stakeholder)"><a
(click)="deleteStakeholderOpen(stakeholder);hide(element)">Delete</a>
</li>
</ul>
</div>
</div>
<a class="uk-display-block uk-text-center uk-link-reset" [routerLink]="'/admin/' + stakeholder.alias">
<div class="titleContainer uk-h6 uk-margin-remove-bottom uk-margin-top multi-line-ellipsis lines-2">
<p *ngIf="stakeholder.name" class="uk-margin-remove">
{{stakeholder.name}}
</p>
</div>
<div class="logoContainer uk-margin-top uk-flex uk-flex-column uk-flex-center uk-flex-middle">
<img [src]="stakeholder | logoUrl" class="uk-blend-multiply" style="max-height: 80px;">
</div>
</a>
</div>
</div>
</ng-template>
<ng-template #newBox let-text="text" let-isDefault="isDefault">
<ng-container *ngIf="!loading">
<div class="uk-card uk-card-default uk-text-center uk-card-body clickable" (click)="editStakeholder(null, isDefault)">
<div class="uk-text-small uk-text-muted">
{{text}}
</div>
<div class="uk-margin-medium-top uk-margin-small-bottom">
<span class="uk-text-secondary">
<icon name="add" [ratio]="3"></icon>
</span>
</div>
</div>
</ng-container>
</ng-template>
<modal-alert #editStakeholderModal [large]="true" classTitle="uk-background-primary uk-light"
(alertOutput)="editStakeholderComponent.save(callback)" (cancelOutput)="editStakeholderComponent.removePhoto()"
[okDisabled]="editStakeholderComponent.disabled">
<div class="uk-height-large uk-position-relative" *ngIf="editStakeholderComponent.loading">
<loading class="uk-position-center"></loading>
</div>
<div class="uk-padding" [class.uk-hidden]="editStakeholderComponent.loading">
<edit-stakeholder #editStakeholderComponent></edit-stakeholder>
</div>
</modal-alert>
<modal-alert #deleteStakeholderModal [overflowBody]="false" (alertOutput)="deleteStakeholder()">
<div class="uk-height-medium uk-position-relative" *ngIf="deleteLoading">
<loading class="uk-position-center"></loading>
</div>
<div *ngIf="!deleteLoading">
This stakeholder will permanently be deleted. Are you sure you want to proceed?
</div>
</modal-alert>

View File

@ -1,23 +0,0 @@
@import (reference) "~src/assets/openaire-theme/less/color.less";
.setType(@color) {
border-bottom: 4px solid fade(@color, 30%);
& .type {
color: @color;
}
}
.uk-card {
&.funder {
.setType(@funder-color);
}
&.ri {
.setType(@ri-color);
}
&.organization {
.setType(@organization-color);
}
}

View File

@ -1,295 +0,0 @@
import {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, StakeholderEntities, Visibility} from "../openaireLibrary/monitor/entities/stakeholder";
import {Subscriber, zip} from "rxjs";
import {StakeholderUtils} from "../utils/indicator-utils";
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
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 {properties} from "../../environments/environment";
import {ActivatedRoute} from "@angular/router";
type Tab = 'all' | 'templates'| 'profiles';
declare var UIkit;
@Component({
selector: 'home',
templateUrl: "./manageStakeholders.component.html",
styleUrls: ["./manageStakeholders.component.less"]
})
export class ManageStakeholdersComponent implements OnInit, OnDestroy {
public properties: EnvProperties;
public loading: boolean = true;
public deleteLoading: boolean = false;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public defaultStakeholders: Stakeholder[];
public stakeholders: Stakeholder[];
public alias: string[];
public stakeholder: Stakeholder;
public index: number;
public user = null;
public tab: Tab = 'all';
public stakeholderEntities = StakeholderEntities;
/**
* Filtered Stakeholders
*/
public displayDefaultStakeholders: Stakeholder[];
public displayStakeholders: Stakeholder[];
/**
* Top filters
*/
public filters: UntypedFormGroup;
public all: Option = {
value: 'all',
label: 'All'
};
public callback: Function;
/**
* Grid or List View
*/
private subscriptions: any[] = [];
@ViewChild('editStakeholderModal', { static: true }) editStakeholderModal: AlertModal;
@ViewChild('deleteStakeholderModal', { static: true }) deleteStakeholderModal: AlertModal;
@ViewChild('editStakeholderComponent', { static: true }) editStakeholderComponent: EditStakeholderComponent;
constructor(private stakeholderService: StakeholderService,
private userManagementService: UserManagementService,
private route: ActivatedRoute,
private title: Title,
private fb: UntypedFormBuilder) {
}
ngOnInit(): void {
this.buildFilters();
this.properties = properties;
this.title.setTitle('Manage profiles');
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}));
let data = zip(
this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL),
this.stakeholderService.getMyStakeholders(this.properties.monitorServiceAPIURL),
this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL)
);
this.subscriptions.push(data.subscribe(res => {
this.defaultStakeholders = res[0];
this.stakeholders = res[1];
this.displayDefaultStakeholders = res[0];
this.displayStakeholders = res[1];
this.alias = res[2];
this.loading = false;
}, error => {
this.loading = false;
}));
}
ngOnDestroy(): void {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
});
}
hide(element: any) {
UIkit.dropdown(element).hide();
}
private buildFilters() {
this.filters = this.fb.group({
status: this.fb.control('all'),
keyword: this.fb.control('')
});
this.subscriptions.push(this.filters.get('status').valueChanges.subscribe(value => {
this.onStatusChange(value);
}));
this.subscriptions.push(this.filters.get('keyword').valueChanges.subscribe(value => {
this.onKeywordChange(value);
}));
}
onStatusChange(value) {
this.displayDefaultStakeholders = this.filterStatus(this.defaultStakeholders, value);
this.displayStakeholders = this.filterStatus(this.stakeholders, value);
}
onKeywordChange(value) {
this.displayDefaultStakeholders = this.filterByKeyword(this.defaultStakeholders, value);
this.displayStakeholders = this.filterByKeyword(this.stakeholders, value);
}
private filterStatus(stakeholders: Stakeholder[], value): Stakeholder[] {
if (value === 'all') {
return stakeholders;
} else {
return stakeholders.filter(stakeholder => stakeholder.visibility == value);
}
}
private filterByKeyword(stakeholders: Stakeholder[], value): Stakeholder[] {
if (!value) {
return stakeholders;
} else {
return stakeholders.filter(stakeholder =>
stakeholder.name && stakeholder.name.toLowerCase().includes(value.toLowerCase()) ||
stakeholder.type && stakeholder.type.toLowerCase().includes(value.toLowerCase()) ||
stakeholder.index_id && stakeholder.index_id.toLowerCase().includes(value.toLowerCase()) ||
stakeholder.index_shortName && stakeholder.index_shortName.toLowerCase().includes(value.toLowerCase()) ||
stakeholder.index_name && stakeholder.index_name.toLowerCase().includes(value.toLowerCase())
);
}
}
public editStakeholder(stakeholder: Stakeholder = null, isDefault: boolean = false) {
if (isDefault) {
this.index = (stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === stakeholder._id) : -1;
} else {
this.index = (stakeholder) ? this.stakeholders.findIndex(value => value._id === stakeholder._id) : -1;
}
if (!stakeholder) {
this.stakeholder = new Stakeholder(null, null, null,
null, null, null, null, null);
} else {
this.stakeholder = stakeholder;
}
this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, isDefault, this.index === -1);
if (this.index !== -1) {
this.callback = (stakeholder: Stakeholder) => {
let index: number;
if (stakeholder.defaultId == null) {
index = this.alias.findIndex(value => value == this.defaultStakeholders[this.index].alias);
this.defaultStakeholders[this.index] = stakeholder;
} else {
index = this.alias.findIndex(value => value == this.stakeholders[this.index].alias);
this.stakeholders[this.index] = stakeholder;
}
if(index != -1) {
this.alias[index] = stakeholder.alias;
}
this.editStakeholderModal.cancel();
};
this.editStakeholderModal.alertTitle = 'Edit ' + this.stakeholder.name;
this.editStakeholderModal.okButtonText = 'Save Changes';
} else {
this.callback = (stakeholder: Stakeholder) => {
if (stakeholder.defaultId === null) {
this.defaultStakeholders.push(stakeholder);
} else {
this.stakeholders.push(stakeholder);
}
this.alias.push(stakeholder.alias);
this.editStakeholderModal.cancel();
};
this.editStakeholderModal.alertTitle = 'Create a new ' + (isDefault?'Default ':'') + 'Profile';
this.editStakeholderModal.okButtonText = 'Create';
}
this.editStakeholderModal.cancelButtonText = 'Cancel';
this.editStakeholderModal.okButtonLeft = false;
this.editStakeholderModal.alertMessage = false;
this.editStakeholderModal.stayOpen = true;
this.editStakeholderModal.open();
}
public deleteStakeholderOpen(stakeholder: Stakeholder) {
this.stakeholder = stakeholder;
this.deleteStakeholderModal.alertTitle = 'Delete ' + this.stakeholder.index_name;
this.deleteStakeholderModal.cancelButtonText = 'No';
this.deleteStakeholderModal.okButtonText = 'Yes';
this.deleteStakeholderModal.alertMessage = false;
this.deleteStakeholderModal.stayOpen = true;
this.deleteStakeholderModal.open();
}
public deleteStakeholder() {
this.deleteLoading = true;
if (!this.stakeholder.defaultId) {
this.index = (this.stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === this.stakeholder._id) : -1;
} else {
this.index = (this.stakeholder) ? this.stakeholders.findIndex(value => value._id === this.stakeholder._id) : -1;
}
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, [this.stakeholder._id]).subscribe(() => {
UIkit.notification(this.stakeholder.name+ ' has been <b>successfully deleted</b>', {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
if (!this.stakeholder.defaultId) {
this.defaultStakeholders.splice(this.index, 1);
} else {
this.stakeholders.splice(this.index, 1);
}
this.alias = this.alias.filter(item => item !== this.stakeholder.alias);
this.deleteLoading = false;
this.deleteStakeholderModal.cancel();
}, error => {
UIkit.notification('An error has occurred. Please try again later', {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
this.deleteLoading = false;
this.deleteStakeholderModal.cancel();
}));
}
changeStakeholderStatus(stakeholder: Stakeholder, visibility: Visibility) {
let path = [
stakeholder._id
];
this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(returnedElement => {
stakeholder.visibility = returnedElement.visibility;
UIkit.notification(stakeholder.name+ '\'s status has been <b>successfully changed</b> to ' + stakeholder.visibility.toLowerCase(), {
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'
});
}));
}
public isManager(): boolean {
return this.isCurator() || (Session.isKindOfMonitorManager(this.user));
}
public isProfileManager(stakeholder: Stakeholder): boolean {
return this.isCurator() || (Session.isManager(stakeholder.type, stakeholder.alias, this.user));
}
public isCurator(): boolean {
return this.isAdmin() || Session.isMonitorCurator(this.user);
}
public isAdmin(): boolean {
return Session.isPortalAdministrator(this.user);
}
private isTab(tab: Tab): boolean {
switch (tab) {
case "all":
return true;
case "profiles":
return true;
case "templates":
return true;
default:
return false;
}
}
}

View File

@ -1,50 +0,0 @@
import {NgModule} from "@angular/core";
import {ManageStakeholdersComponent} from "./manageStakeholders.component";
import {ManageStakeholdersRoutingModule} from "./manageStakeholders-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 "../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";
import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module";
import {SearchInputModule} from "../openaireLibrary/sharedComponents/search-input/search-input.module";
import {
SidebarMobileToggleModule
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
import {SliderTabsModule} from "../openaireLibrary/sharedComponents/tabs/slider-tabs.module";
@NgModule({
declarations: [ManageStakeholdersComponent],
imports: [
ManageStakeholdersRoutingModule,
CommonModule,
RouterModule,
InputModule,
LoadingModule,
AlertModalModule,
ReactiveFormsModule,
EditStakeholderModule,
IconsModule,
PageContentModule,
LogoUrlPipeModule,
SearchInputModule,
SidebarMobileToggleModule,
SliderTabsModule
],
providers: [
PreviousRouteRecorder,
],
exports: [ManageStakeholdersComponent]
})
export class ManageStakeholdersModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([earth, incognito, restricted]);
}
}

View File

@ -47,7 +47,7 @@
<sidebar-mobile-toggle *ngIf="isMobile" [class.uk-margin-bottom]="!activeCategory || countSubCategoriesToShow(activeCategory) <= 1" class="uk-margin-top uk-display-block"></sidebar-mobile-toggle>
<div *ngIf="activeCategory && countSubCategoriesToShow(activeCategory) > 1"
[class.uk-margin-bottom]="isMobile" class="uk-margin-medium-top">
<slider-tabs *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" [border]="!isMobile"
<slider-tabs *ngIf="stakeholder && !loading && activeTopic" [border]="!isMobile"
[tabsClass]="isMobile?'uk-subnav uk-subnav-pill-alt uk-text-small':'uk-tab'" [type]="'dynamic'">
<ng-template ngFor [ngForOf]="activeCategory.subCategories" let-subCategory>
<slider-tab *ngIf="hasPermission(subCategory.visibility)" [tabTitle]="subCategory.name"
@ -103,18 +103,18 @@
<div *ngIf="hasPermission(indicator.visibility)" [ngClass]="getNumberClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-padding-small number-card uk-position-relative"
[class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div *ngIf="!indicator.descriptionOverlay">
<div *ngIf="!indicator.overlay">
<div
class="uk-text-small uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
<div class="number uk-text-small uk-text-bold">
<span *ngIf="numberResults.get(i + '-' + j)"
[innerHTML]="numberResults.get(i + '-' + j) | numberRound: 2:1"></span>
[innerHTML]="(indicator.indicatorPaths[0].format == 'NUMBER'?(numberResults.get(i + '-' + j) | numberRound: 2:1:stakeholder.locale):(numberResults.get(i + '-' + j) | numberPercentage: stakeholder.locale))"></span>
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
</div>
<div *ngIf="indicator.description || indicator.additionalDescription"
class="uk-position-top-right uk-text-center uk-margin-small-top uk-margin-small-right uk-visible@m">
<a class="uk-display-inline-block uk-button uk-button-link" uk-tooltip="Note"
(click)="toggleDescriptionOverlay($event, indicator)">
(click)="changeOverlay($event, indicator, 'description')">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
</span>
@ -122,12 +122,12 @@
</div>
</div>
<div
*ngIf="indicator.descriptionOverlay && (indicator.description || indicator.additionalDescription)"
*ngIf="indicator.overlay && (indicator.description || indicator.additionalDescription)"
click-outside-or-esc class="uk-overflow-auto"
(clickOutside)="closeDescriptionOverlay($event, indicator)">
(clickOutside)="closeOverlay($event, indicator)">
<div class="uk-position-top-right uk-text-center uk-margin-small-top uk-margin-small-right">
<a class="uk-display-inline-block uk-button uk-button-link"
(click)="toggleDescriptionOverlay($event, indicator)">
(click)="changeOverlay($event, indicator, false)">
<span class="uk-flex uk-flex-middle">
<icon name="close" type="outlined" [flex]="true"></icon>
</span>
@ -154,12 +154,12 @@
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="hasPermission(indicator.visibility)" [ngClass]="getNumberClassBySize(indicator.width)">
<div [class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div *ngIf="!indicator.descriptionOverlay">
<div *ngIf="!indicator.overlay">
<div
class="uk-text-xsmall uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
<div class="number uk-text-small uk-text-bold">
<span *ngIf="numberResults.get(i + '-' + j)"
[innerHTML]="numberResults.get(i + '-' + j) | numberRound: 2:1"></span>
[innerHTML]="(indicator.indicatorPaths[0].format == 'NUMBER'?(numberResults.get(i + '-' + j) | numberRound: 2:1:stakeholder.locale):(numberResults.get(i + '-' + j) | numberPercentage: stakeholder.locale))"></span>
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
</div>
</div>
@ -183,8 +183,8 @@
<div class="uk-card uk-card-default uk-position-relative"
[class.semiFiltered]="chartsActiveType.get(i + '-' + j).filtersApplied < countSelectedFilters()">
<div class="uk-card-body uk-text-center uk-margin-small-bottom">
<h6 class="uk-margin-bottom chartTitle uk-flex uk-flex-bottom ">
<div>{{indicator.name + " "}}</div>
<h6 class="uk-margin-bottom chartTitle uk-flex uk-flex-bottom">
{{indicator.name + " "}}
</h6>
<div *ngIf="indicator.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of indicator.indicatorPaths;"
@ -212,23 +212,22 @@
class="uk-width-1-1 uk-blend-multiply"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')">
</div>
<div *ngIf="indicator.description || indicator.additionalDescription"
class="uk-position-bottom-left uk-margin-left uk-margin-small-bottom uk-visible@m">
<a class="uk-display-inline-block uk-button uk-button-text"
(click)="toggleDescriptionOverlay($event, indicator)">
<div class="uk-position-bottom-left uk-margin-left uk-margin-small-bottom uk-visible@m">
<a *ngIf="indicator.description || indicator.additionalDescription"
class="uk-display-inline-block uk-button uk-button-text"
(click)="changeOverlay($event, indicator, 'description')">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
<span class="uk-margin-small-left">Note</span>
</span>
</a>
</div>
<div *ngIf="indicator.descriptionOverlay && (indicator.description || indicator.additionalDescription)"
class="indicator-description uk-card uk-card-default uk-flex uk-flex-middle uk-flex-center">
<div class="inner" click-outside-or-esc
(clickOutside)="closeDescriptionOverlay($event, indicator)">
<div *ngIf="indicator.overlay" class="indicator-overlay uk-card uk-card-default uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="indicator.overlay == 'description'" class="inner" click-outside-or-esc
(clickOutside)="closeOverlay($event, indicator)">
<div class="uk-padding-small">
<div class="uk-flex uk-flex-right">
<button class="uk-close uk-icon" (click)="toggleDescriptionOverlay($event, indicator)">
<button class="uk-close uk-icon" (click)="changeOverlay($event, indicator, false)">
<icon name="close" ratio="1"></icon>
</button>
</div>
@ -260,12 +259,13 @@
uk-grid>
<!-- Last Stats Date-->
<div class="uk-width-expand@m uk-width-1-1">
<icon name="graph" customClass="text-graph"></icon>
<span class="uk-margin-small-left uk-text-baseline uk-text-meta">Powered by </span>
<a href="https://graph.openaire.eu" class="text-graph">OpenAIRE Research Graph</a>
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@m">
<img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 16px;">
</a>
<span *ngIf="statsUpdateDate" class="uk-text-baseline uk-text-meta">
. Last update of statistics in OpenAIRE: {{statsUpdateDate | date: 'MMM dd, yyyy'}}
</span>
<span class="uk-margin-xsmall-left uk-margin-xsmall-right">-</span>
<span>Last update of statistics in OpenAIRE: {{statsUpdateDate | date: 'MMM dd, yyyy'}}</span>
</span>
</div>
<!--Feedback-->
<div class="uk-width-auto@m uk-width-1-1">
@ -276,14 +276,14 @@
</div>
</ng-template>
</div>
<div *ngIf="stakeholder && !privateStakeholder " href="#style_switcher" uk-toggle="" id="filters_switcher_toggle"
class="uk-offcanvas-switcher uk-flex uk-flex-center uk-flex-middle">
<a *ngIf="stakeholder && !privateStakeholder " href="#style_switcher" uk-toggle="" id="filters_switcher_toggle"
class="uk-offcanvas-switcher uk-flex uk-flex-center uk-flex-middle uk-link-reset">
<icon name="filters" ratio="1.5" visuallyHidden="Filters" gradient="filters_icon"></icon>
<span [class.uk-hidden]="countSelectedFilters() === 0"
class="uk-offcanvas-count uk-flex uk-flex-middle uk-flex-center">
{{countSelectedFilters()}}
</span>
</div>
</a>
<div *ngIf="stakeholder && !privateStakeholder" id="style_switcher" class="uk-offcanvas"
uk-offcanvas="flip:true; overlay: true">
<div class="uk-offcanvas-bar">
@ -301,9 +301,8 @@
<div *ngIf="!user" class="uk-margin-top"><a class="uk-link" (click)="logIn()"> Sign in</a> to apply filters.</div>
<ul *ngIf="user" class="uk-list uk-list-xlarge uk-list-divider uk-margin-top">
<li>
<range-filter #rangeFilter [filter]="periodFilter" yearMin="2000" [yearMax]="currentYear"
[mandatoryRange]="true"
(onFilterChange)="filter()"></range-filter>
<range-filter #rangeFilter [filter]="periodFilter"[yearMin]="minYear" [yearMax]="maxYear"
[mandatoryRange]="true" (onFilterChange)="filter()"></range-filter>
</li>
<ng-container *ngFor="let filter of filters ">
<li *ngIf="filter.values.length >0">
@ -319,7 +318,7 @@
</div>
</div>
<!-- <div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" id="print_toggle"
<!-- <div *ngIf="stakeholder && !loading && activeTopic" id="print_toggle"
class="uk-offcanvas-switcher uk-flex uk-flex-center uk-flex-middle" (click)="printReport()">
<icon name="print" ratio="1.5" customClass="uk-text-background" visuallyHidden="Print"></icon>
</div> -->

View File

@ -5,20 +5,3 @@
opacity: 0.5;
}
}
.indicator-description {
position: absolute;
top: 0;
left: 0;
background: @global-overlay-background;
width: 100%;
height: 100%;
.inner {
background: @global-background;
border-radius: @global-border-radius;
width: 75%;
max-height: 75%;
overflow: auto;
}
}

View File

@ -1,116 +1,47 @@
import {ChangeDetectorRef, Component, HostListener, OnDestroy, OnInit, ViewChild, ViewRef} from '@angular/core';
import {ActivatedRoute, Params, Router} from '@angular/router';
import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {DomSanitizer, Meta, Title} from '@angular/platform-browser';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
import {Dates, StringUtils} from '../openaireLibrary/utils/string-utils.class';
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
import {ErrorMessagesComponent} from '../openaireLibrary/utils/errorMessages.component';
import {HelperService} from "../openaireLibrary/utils/helper/helper.service";
import {StringUtils} from '../openaireLibrary/utils/string-utils.class';
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
import {
Category,
Indicator,
IndicatorPath,
IndicatorSize,
Section,
Stakeholder,
SubCategory,
Topic,
Visibility
} from "../openaireLibrary/monitor/entities/stakeholder";
import {StatisticsService} from "../utils/services/statistics.service";
import {IndicatorUtils} from "../utils/indicator-utils";
import {IndicatorPath} from "../openaireLibrary/monitor/entities/stakeholder";
import {StatisticsService} from "../openaireLibrary/monitor-admin/utils/services/statistics.service";
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {UntypedFormBuilder, UntypedFormControl} from "@angular/forms";
import {Subscriber, Subscription} from "rxjs";
import {Session, User} from "../openaireLibrary/login/utils/helper.class";
import {Subscription} from "rxjs";
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
import {RangeFilter} from "../openaireLibrary/utils/rangeFilter/rangeFilterHelperClasses.class";
import {Filter, Value} from "../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class";
import {RouterHelper} from "../openaireLibrary/utils/routerHelper.class";
import {properties} from "../../environments/environment";
import {IndexInfoService} from "../openaireLibrary/utils/indexInfo.service";
import {ConfigurationService} from "../openaireLibrary/utils/configuration/configuration.service";
import {ClickEvent} from '../openaireLibrary/utils/click/click-outside-or-esc.directive';
import {RangeFilterComponent} from "../openaireLibrary/utils/rangeFilter/rangeFilter.component";
import {
MonitorIndicatorStakeholderBaseComponent
} from "../openaireLibrary/monitor/monitor-indicator-stakeholder-base.component";
@Component({
selector: 'monitor',
templateUrl: 'monitor.component.html',
styleUrls: ['monitor.component.less']
})
export class MonitorComponent implements OnInit, OnDestroy {
public user: User;
public subscriptions: any[] = [];
piwikSiteId;
title;
description;
public pageContents = null;
public divContents = null;
public status: number;
public loading: boolean = true;
public view: Visibility;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public activeTopic: Topic = null;
public activeCategory: Category = null;
public activeSubCategory: SubCategory = null;
public errorCodes: ErrorCodes;
public stakeholder: Stakeholder;
public numberResults: Map<string, number> = new Map<string, number>();
public chartsActiveType: Map<string, IndicatorPath> = new Map<string, IndicatorPath>();
private errorMessages: ErrorMessagesComponent;
properties: EnvProperties = properties;
public routerHelper: RouterHelper = new RouterHelper();
filters: Filter[] = [];
queryParams = {};
public currentYear = new Date().getFullYear();
periodFilter: RangeFilter = {
title: "Time range",
filterId: "year",
originalFilterIdFrom: null,
originalFilterIdTo: null,
selectedFromValue: null,
selectedToValue: null,
selectedFromAndToValues: ""
};
export class MonitorComponent extends MonitorIndicatorStakeholderBaseComponent implements OnInit {
@ViewChild('rangeFilter') rangeFilter: RangeFilterComponent;
privateStakeholder = false;
public keyword: UntypedFormControl;
public statsUpdateDate: Date;
public isFullscreen: boolean = false;
public isMobile: boolean = false;
@HostListener('fullscreenchange', ['$event'])
@HostListener('webkitfullscreenchange', ['$event'])
@HostListener('mozfullscreenchange', ['$event'])
@HostListener('MSFullscreenChange', ['$event'])
screenChange(event) {
this.isFullscreen = !this.isFullscreen;
}
constructor(
private route: ActivatedRoute,
private _router: Router,
private _meta: Meta,
private _title: Title,
private _piwikService: PiwikService,
private helper: HelperService,
protected _route: ActivatedRoute,
protected _router: Router,
protected _meta: Meta,
protected _title: Title,
protected _piwikService: PiwikService,
protected seoService: SEOService,
protected sanitizer: DomSanitizer,
protected cdr: ChangeDetectorRef,
protected layoutService: LayoutService,
protected statisticsService: StatisticsService,
private stakeholderService: StakeholderService,
private userManagementService: UserManagementService,
private statisticsService: StatisticsService,
private layoutService: LayoutService,
private seoService: SEOService,
private cdr: ChangeDetectorRef,
private indexInfoService: IndexInfoService,
private sanitizer: DomSanitizer, private _fb: UntypedFormBuilder, private router: Router,
private configurationService: ConfigurationService) {
this.errorCodes = new ErrorCodes();
this.errorMessages = new ErrorMessagesComponent();
this.status = this.errorCodes.LOADING;
private indexInfoService: IndexInfoService) {
super();
}
public ngOnInit() {
@ -121,15 +52,11 @@ export class MonitorComponent implements OnInit, OnDestroy {
}
}));
}
this.keyword = this._fb.control('');
let subscription: Subscription;
this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
this.cdr.detectChanges();
});
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
this.subscriptions.push(this.route.params.subscribe(params => {
this.subscriptions.push(this._route.params.subscribe(params => {
this.loading = true;
this.activeTopic = null;
this.activeCategory = null;
@ -137,9 +64,7 @@ export class MonitorComponent implements OnInit, OnDestroy {
if (subscription) {
subscription.unsubscribe();
}
var url = properties.domain + properties.baseLink + this._router.url;
if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder']) {
this.status = this.errorCodes.LOADING;
this.numberResults = new Map<string, number>();
this.chartsActiveType = new Map<string, IndicatorPath>();
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
@ -175,33 +100,15 @@ export class MonitorComponent implements OnInit, OnDestroy {
, filterOperator: "or", valueIsExact: true, filterType: "checkbox", radioValue: ""
});
}
this.subscriptions.push(this.route.queryParams.subscribe( queryParams => {
this.subscriptions.push(this._route.queryParams.subscribe(queryParams => {
this.handleQueryParams(queryParams, params);
this.seoService.createLinkForCanonicalURL(url, false);
this._meta.updateTag({content: url}, "property='og:url'");
this.description = "Monitor Dashboard | " + this.stakeholder.name;
this.title = "Monitor Dashboard | " + this.stakeholder.name;
this._meta.updateTag({content: this.description}, "name='description'");
this._meta.updateTag({content: this.description}, "property='og:description'");
this._meta.updateTag({content: this.title}, "property='og:title'");
this._title.setTitle(this.title);
if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal && portal.piwik) {
this.piwikSiteId = portal.piwik;
this.subscriptions.push(this._piwikService.trackView(this.properties, this.title, this.piwikSiteId).subscribe());
}
}));
}
this.description = "Monitor Dashboard | " + this.stakeholder.name;
this.setMetadata();
if (this.hasPermission((this.view && this.isManager(this.stakeholder))?this.view:this.stakeholder.visibility)) {
//this.getDivContents();
// this.getPageContents();
this.status = this.errorCodes.DONE;
this.setView(params);
} else {
this.privateStakeholder = true;
// this.navigateToError();
if (subscription) {
subscription.unsubscribe();
}
@ -216,220 +123,15 @@ export class MonitorComponent implements OnInit, OnDestroy {
});
this.subscriptions.push(subscription);
} else {
if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
if (this.piwikSiteId) {
this.subscriptions.push(this._piwikService.trackView(this.properties, this.title, this.piwikSiteId).subscribe());
}
}
this.subscriptions.push(this.route.queryParams.subscribe( queryParams => {
this.trackView();
this.subscriptions.push(this._route.queryParams.subscribe(queryParams => {
this.handleQueryParams(queryParams, params);
}));
}
}));
}));
}
get monitorLink() {
return "https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu';
}
private handleQueryParams(queryParams, params) {
this.queryParams = Object.assign({}, queryParams);
this.initializeFilters();
this.setView(params);
if(!this.user && (this.filters.filter(filter => this.queryParams[filter.filterId]).length > 0 || this.queryParams['year'])) {
if(queryParams['view']) {
this.router.navigate([], {queryParams: {view: queryParams['view']}});
} else {
this.router.navigate([], {queryParams: {}});
}
}
this.view = queryParams['view'];
}
private initializeFilters() {
this.periodFilter.selectedFromValue = (this.queryParams['year'] && this.queryParams['year'].indexOf("range") == 0) ? this.queryParams['year'].split("range")[1].split(":")[0] : "";
this.periodFilter.selectedToValue = (this.queryParams['year'] && this.queryParams['year'].indexOf("range") == 0) ? this.queryParams['year'].split("range")[1].split(":")[1] : "";
this.validateYearRange(false);
for (let filter of this.filters) {
if (this.queryParams[filter.filterId]) {
for (let value of filter.values) {
if (value.id == StringUtils.URIDecode(StringUtils.unquote(this.queryParams[filter.filterId]))) {
value.selected = true;
filter.countSelectedValues = 1;
break;
}
}
} else {
this.clearFilter(filter);
}
}
}
private validateYearRange(navigateTo: boolean = false) {
let validYears = true;
if (this.periodFilter.selectedToValue && (this.periodFilter.selectedToValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedToValue, Dates.currentYear - 20, Dates.currentYear))) {
this.periodFilter.selectedToValue = Dates.currentYear + "";
validYears = false;
}
if (this.periodFilter.selectedFromValue && (this.periodFilter.selectedFromValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedFromValue, Dates.currentYear - 20, Dates.currentYear))) {
this.periodFilter.selectedFromValue = Dates.currentYear - 20 + "";
validYears = false;
}
if (this.periodFilter.selectedFromValue && this.periodFilter.selectedFromValue.length && this.periodFilter.selectedToValue && this.periodFilter.selectedToValue.length > 0 && parseInt(this.periodFilter.selectedFromValue, 10) > parseInt(this.periodFilter.selectedToValue, 10)) {
this.periodFilter.selectedFromValue = this.periodFilter.selectedToValue;
validYears = false;
}
if (!validYears || navigateTo) {
if (this.periodFilter.selectedFromValue || this.periodFilter.selectedToValue) {
this.queryParams["year"] = 'range' + (this.periodFilter.selectedFromValue ? this.periodFilter.selectedFromValue : '') + ":" + (this.periodFilter.selectedToValue ? this.periodFilter.selectedToValue : "");
} else {
delete this.queryParams["year"];
}
// this.location.go(location.pathname, this.routerHelper.createQueryParamsString( Object.keys(this.queryParams), Object.values(this.queryParams)));
this.router.navigate([], {queryParams: this.queryParams});
this.setIndicators();
}
}
clearAll() {
for (let filter of this.filters) {
this.clearFilter(filter);
}
this.periodFilter.selectedFromValue = "";
this.periodFilter.selectedToValue = "";
this.validateYearRange(true)
}
clearFilter(filter: Filter) {
filter.countSelectedValues = 0;
filter.radioValue = "";
for (let value of filter.values) {
if (value.selected) {
value.selected = false;
}
}
if (this.queryParams[filter.filterId]) {
delete this.queryParams[filter.filterId];
}
}
countSelectedFilters(): number {
let count = 0;
if (this.periodFilter.selectedFromAndToValues.length > 0) {
count += 1;
}
for (let filter of this.filters) {
count += filter.countSelectedValues;
}
return count;
}
public get open() {
return this.layoutService.open;
}
private getPageContents() {
this.subscriptions.push(this.helper.getPageHelpContents(this.properties, this.properties.adminToolsCommunity, this._router.url).subscribe(contents => {
this.pageContents = contents;
}));
}
private getDivContents() {
this.subscriptions.push(this.helper.getDivHelpContents(this.properties, this.properties.adminToolsCommunity, this._router.url).subscribe(contents => {
this.divContents = contents;
}));
}
private setView(params: Params) {
this.loading = false;
if (params['topic']) {
this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && this.hasPermission(topic.visibility));
if (this.activeTopic) {
if (params['category']) {
this.activeCategory = this.activeTopic.categories.find(category =>
(category.alias === params['category']) && this.hasPermission(category.visibility));
if (!this.activeCategory) {
this.navigateToError();
return;
}
} else {
this.activeCategory = this.activeTopic.categories.find(category => this.hasPermission(category.visibility));
if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
this.hasPermission(subCategory.visibility));
if (this.activeSubCategory) {
this.setIndicators();
}
}
return;
}
if (this.activeCategory) {
if (params['subCategory']) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
(subCategory.alias === params['subCategory'] && this.hasPermission(subCategory.visibility)));
if (!this.activeSubCategory) {
this.navigateToError();
return;
}
} else {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
this.hasPermission(subCategory.visibility));
}
if (this.activeSubCategory) {
this.setIndicators();
} else {
this.navigateToError();
}
return;
} else {
this.activeSubCategory = null;
}
} else {
this.navigateToError();
return;
}
} else {
this.activeTopic = this.stakeholder.topics.find(topic => this.hasPermission(topic.visibility));
if (this.activeTopic) {
this.activeCategory = this.activeTopic.categories.find(category => this.hasPermission(category.visibility));
if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.hasPermission(subCategory.visibility));
if (this.activeSubCategory) {
this.setIndicators();
}
}
}
}
}
filter() {
this.validateYearRange(true);
}
filterChanged($event, navigate: boolean = true) {
let selected = "";
for (let value of $event.value.values) {
if (value.selected) {
selected = value.id;
break;
}
}
if (selected) {
this.queryParams[$event.value.filterId] = StringUtils.quote(StringUtils.URIEncode(selected));
} else {
delete this.queryParams[$event.value.filterId];
}
if (navigate) {
this.router.navigate([], {queryParams: this.queryParams});
this.setIndicators();
}
}
private getfl0() {
if (this.queryParams["relfundinglevel0_id"] && this.filters.length > 0) {
let value = StringUtils.URIDecode(StringUtils.unquote(this.queryParams["relfundinglevel0_id"]));
@ -437,189 +139,23 @@ export class MonitorComponent implements OnInit, OnDestroy {
}
return null;
}
private getCoFunded() {
if (this.queryParams["co-funded"] && this.filters.length > 0) {
return this.queryParams["co-funded"] && StringUtils.URIDecode(StringUtils.unquote(this.queryParams["co-funded"])) == "co-funded-results";
}
return false;
}
clearPeriodFilter() {
if (this.periodFilter.selectedFromValue || this.periodFilter.selectedToValue) {
this.periodFilter.selectedFromValue = "";
this.periodFilter.selectedToValue = "";
if(this.rangeFilter) {
this.rangeFilter.clearFilter();
}
this.filter();
}
}
clearFilterValue(filter: Filter, value: Value) {
value.selected = false;
filter.radioValue = '';
filter.countSelectedValues = filter.countSelectedValues - 1;
this.filterChanged({
value:filter
});
}
private setIndicators() {
this.periodFilter.selectedFromAndToValues = (this.periodFilter.selectedFromValue || this.periodFilter.selectedToValue ? ((this.periodFilter.selectedFromValue && !this.periodFilter.selectedToValue ? "From " : "") + (!this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? "Until " : "") + (this.periodFilter.selectedFromValue ? this.periodFilter.selectedFromValue : "") +
(this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? " - " : "") + (this.periodFilter.selectedToValue ? this.periodFilter.selectedToValue : "")) : "");
//clear numbers when filters change
this.numberResults.clear();
let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>();
this.activeSubCategory.numbers.forEach((section, i) => {
section.indicators.forEach((number, j) => {
if (this.hasPermission(number.visibility)) {
let url = this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, number.indicatorPaths[0], this.getfl0(), this.periodFilter.selectedFromValue, this.periodFilter.selectedToValue, this.getCoFunded());
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);
}
});
});
urls.forEach((indexes, pair) => {
pair = JSON.parse(pair);
let activeSubcategory = this.activeSubCategory._id;
this.subscriptions.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(pair[0]), pair[1]).subscribe(response => {
if(activeSubcategory === this.activeSubCategory._id) {
indexes.forEach(([i, j]) => {
if( this.activeSubCategory?.numbers[i]?.indicators[j]) {
let result = JSON.parse(JSON.stringify(response));
this.activeSubCategory.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);
}
});
}
}));
});
this.activeSubCategory.charts.forEach((section, i) => {
section.indicators.forEach((indicator, j) => {
if (indicator.indicatorPaths.length > 0) {
indicator.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[0]);
this.chartsActiveType.set(i + '-' + j, indicator.indicatorPaths[0]);
}
});
});
if (this.cdr && !(this.cdr as ViewRef).destroyed) {
this.cdr.detectChanges();
}
}
public getUrlByStakeHolder(indicatorPath: IndicatorPath) {
return this.sanitizer.bypassSecurityTrustResourceUrl(
this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, indicatorPath, this.getfl0(), this.periodFilter.selectedFromValue, this.periodFilter.selectedToValue, this.getCoFunded())));
}
public setActiveChart(i: number, j: number, type: string) {
let activeChart = this.activeSubCategory.charts[i].indicators[j].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0];
activeChart.safeResourceUrl = this.getUrlByStakeHolder(activeChart);
this.chartsActiveType.set(i + '-' + j, activeChart);
}
private navigateToError() {
this._router.navigate([this.properties.errorLink], {queryParams: {'page': this._router.url}});
}
public quote(param: string): string {
return StringUtils.quote(param);
}
public ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
public isMember(stakeholder: Stakeholder) {
return this.user && (Session.isPortalAdministrator(this.user) || Session.isCurator(stakeholder.type, this.user)
|| Session.isManager(stakeholder.type, stakeholder.alias, this.user) || Session.isMember(stakeholder.type, stakeholder.alias, this.user));
}
public isManager(stakeholder: Stakeholder) {
return this.user && (Session.isPortalAdministrator(this.user) || Session.isCurator(stakeholder.type, this.user) || Session.isManager(stakeholder.type, stakeholder.alias, this.user));
}
public hasPermission(visibility: Visibility): boolean {
if(visibility === 'PUBLIC') {
return true;
} else if(visibility === 'RESTRICTED') {
return (!this.view || this.view === 'RESTRICTED') && this.isMember(this.stakeholder);
} else {
return !this.view && this.isManager(this.stakeholder);
}
}
public countSubCategoriesToShow(category: Category): number {
return category.subCategories.filter(subCategory => this.hasPermission(subCategory.visibility)).length;
}
public countSectionsWithIndicatorsToShow(sections: Section[]):number {
return sections.map(section => this.countIndicatorsToShow(section.indicators)).reduce((sum, current) => sum + current, 0);
}
public countIndicatorsToShow(indicators: Indicator[]): number {
return indicators.filter(indicator => this.hasPermission(indicator.visibility)).length;
public getFullUrl(indicatorPath: IndicatorPath) {
return this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, indicatorPath, this.getfl0(), this.periodFilter.selectedFromValue, this.periodFilter.selectedToValue, this.getCoFunded());
}
public get feedback() {
return "mailto:" + this.properties.feedbackmail + "?subject=%5BOpenAIRE%20Monitor%5D%20" + (this.stakeholder ? this.stakeholder.name : "") + "%20dashboard%20feedback"
}
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 printReport() {
window.print();
}
logIn() {
this.userManagementService.login();
}
toggleDescriptionOverlay(event, indicator: Indicator) {
event.stopPropagation();
indicator.descriptionOverlay = !indicator.descriptionOverlay;
}
closeDescriptionOverlay(event: ClickEvent, indicator: Indicator) {
if(event.clicked && indicator.descriptionOverlay) {
indicator.descriptionOverlay = false;
}
}
}

View File

@ -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";
@ -23,7 +23,7 @@ import {SearchFilterModule} from "../openaireLibrary/searchPages/searchUtils/sea
import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {IconsService} from '../openaireLibrary/utils/icons/icons.service';
import {IconsModule} from '../openaireLibrary/utils/icons/icons.module';
import {filters, graph, incognito} from "../openaireLibrary/utils/icons/icons";
import {filters, incognito} from "../openaireLibrary/utils/icons/icons";
import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.module";
import {NumberRoundModule} from "../openaireLibrary/utils/pipes/number-round.module";
import {SliderTabsModule} from "../openaireLibrary/sharedComponents/tabs/slider-tabs.module";
@ -53,6 +53,6 @@ import {
})
export class MonitorModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([incognito, filters, graph]);
this.iconsService.registerIcons([incognito, filters]);
}
}

@ -1 +1 @@
Subproject commit 2ec6d4cdbae98bb0ac0257b3ea28ead9f0c07ffd
Subproject commit 44e821b1f16f2edbdf58510d18fbe47a1083edd3

View File

@ -2,22 +2,20 @@ import {Component} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {StakeholderService} from "../../../openaireLibrary/monitor/services/stakeholder.service";
import {Subscriber} from "rxjs";
import {ConfigurationService} from "../../../openaireLibrary/utils/configuration/configuration.service";
@Component({
selector: 'monitor-dataprovider',
template: `
<div id="page_content">
<dataprovider *ngIf="initialized" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></dataprovider>
<dataprovider *ngIf="initialized" [communityId]="communityId"></dataprovider>
</div>`,
})
export class MonitorDataProviderComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -34,11 +32,6 @@ export class MonitorDataProviderComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,16 +7,15 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-dataset',
template: `
<result-landing *ngIf="initialized" type="dataset" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></result-landing>
<result-landing *ngIf="initialized" type="dataset" [communityId]="communityId"></result-landing>
`,
})
export class MonitorDatasetComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -33,11 +32,6 @@ export class MonitorDatasetComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,18 +7,20 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-organization',
template: `
<organization *ngIf="initialized" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></organization>
<organization *ngIf="initialized" [communityId]="communityId"></organization>
`,
})
export class MonitorOrganizationComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
@ -26,6 +28,7 @@ export class MonitorOrganizationComponent {
}
});
}
ngOnInit() {
this.subscriptions.push(this.route.params.subscribe(params => {
if (params['stakeholder']) {
@ -33,11 +36,6 @@ export class MonitorOrganizationComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,17 +7,17 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-orp',
template: `
<result-landing *ngIf="initialized" type="orp" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></result-landing>
<result-landing *ngIf="initialized" type="orp" [communityId]="communityId"></result-landing>
`,
})
export class MonitorOrpComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -34,11 +34,6 @@ export class MonitorOrpComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,16 +7,16 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-project',
template: `
<project *ngIf="initialized" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></project>
<project *ngIf="initialized" [communityId]="communityId"></project>
`,
})
export class MonitorProjectComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -33,11 +33,6 @@ export class MonitorProjectComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,16 +7,16 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-publication',
template: `
<result-landing *ngIf="initialized" type="publication" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></result-landing>
<result-landing *ngIf="initialized" type="publication" [communityId]="communityId"></result-landing>
`,
})
export class MonitorPublicationComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -33,11 +33,6 @@ export class MonitorPublicationComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,16 +7,16 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-result',
template: `
<result-landing *ngIf="initialized" type="result" [communityId]="communityId" [piwikSiteId]="piwikSiteId"></result-landing>
<result-landing *ngIf="initialized" type="result" [communityId]="communityId"></result-landing>
`,
})
export class MonitorResultComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -33,11 +33,6 @@ export class MonitorResultComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -7,16 +7,16 @@ import {ConfigurationService} from "../../../openaireLibrary/utils/configuration
@Component({
selector: 'monitor-software',
template: `
<result-landing *ngIf="initialized" type="software" [piwikSiteId]="piwikSiteId"></result-landing>
<result-landing *ngIf="initialized" type="software"></result-landing>
`,
})
export class MonitorSoftwareComponent {
initialized: boolean = false;
communityId;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -33,11 +33,6 @@ export class MonitorSoftwareComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
}
}));
}

View File

@ -15,14 +15,14 @@ import {RouterModule} from "@angular/router";
{ path: 'advanced/dataproviders', loadChildren: () => import('./searchPages/advanced/searchDataProviders.module').then(m => m.MonitorAdvancedSearchDataProvidersModule)},
{ path: 'advanced/organizations', loadChildren: () => import('./searchPages/advanced/searchOrganizations.module').then(m => m.MonitorAdvancedSearchOrganizationsModule)},
// Landing Pages
{ path: 'result', loadChildren: () => import('./landingPages/result/libResult.module').then(m => m.LibResultModule)},
{ path: 'publication', loadChildren: () => import('./landingPages/publication/libPublication.module').then(m => m.LibPublicationModule)},
{ path: 'dataset', loadChildren: () => import('./landingPages/dataset/libDataset.module').then(m => m.LibDatasetModule)},
{ path: 'software', loadChildren: () => import('./landingPages/software/libSoftware.module').then(m => m.LibSoftwareModule)},
{ path: 'other', loadChildren: () => import('./landingPages/orp/libOrp.module').then(m => m.LibOrpModule)},
{ path: 'project', loadChildren: () => import('./landingPages/project/libProject.module').then(m => m.LibProjectModule)},
{ path: 'dataprovider', loadChildren: () => import('./landingPages/dataProvider/libDataProvider.module').then(m => m.LibDataProviderModule)},
{ path: 'organization', loadChildren: () => import('./landingPages/organization/libOrganization.module').then(m => m.LibOrganizationModule)},
{ path: 'result', loadChildren: () => import('./landingPages/result/libResult.module').then(m => m.LibResultModule), data: {hasMenuSearchBar: true}},
{ path: 'publication', loadChildren: () => import('./landingPages/publication/libPublication.module').then(m => m.LibPublicationModule), data: {hasMenuSearchBar: true}},
{ path: 'dataset', loadChildren: () => import('./landingPages/dataset/libDataset.module').then(m => m.LibDatasetModule), data: {hasMenuSearchBar: true}},
{ path: 'software', loadChildren: () => import('./landingPages/software/libSoftware.module').then(m => m.LibSoftwareModule), data: {hasMenuSearchBar: true}},
{ path: 'other', loadChildren: () => import('./landingPages/orp/libOrp.module').then(m => m.LibOrpModule), data: {hasMenuSearchBar: true}},
{ path: 'project', loadChildren: () => import('./landingPages/project/libProject.module').then(m => m.LibProjectModule), data: {hasMenuSearchBar: true}},
{ path: 'dataprovider', loadChildren: () => import('./landingPages/dataProvider/libDataProvider.module').then(m => m.LibDataProviderModule), data: {hasMenuSearchBar: true}},
{ path: 'organization', loadChildren: () => import('./landingPages/organization/libOrganization.module').then(m => m.LibOrganizationModule), data: {hasMenuSearchBar: true}},
])]
})
export class SearchModule {}

View File

@ -3,7 +3,6 @@ import {SearchCustomFilter} from "../../../openaireLibrary/searchPages/searchUti
import {ActivatedRoute, Router} from "@angular/router";
import {StakeholderService} from "../../../openaireLibrary/monitor/services/stakeholder.service";
import {Subscriber} from "rxjs";
import {ConfigurationService} from "../../../openaireLibrary/utils/configuration/configuration.service";
import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSearchPage.component";
@Component({
@ -11,7 +10,7 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
template: `
<search-dataproviders *ngIf="initialized" [simpleView]="false"
[customFilter]=customFilter [hasPrefix]="false" [searchForm]="searchForm"
[includeOnlyResultsAndFilter]="false" [showSwitchSearchLink]="showSwitchSearchLink" [piwikSiteId]="piwikSiteId">
[includeOnlyResultsAndFilter]="false" [showSwitchSearchLink]="showSwitchSearchLink">
</search-dataproviders>
`
})
@ -19,13 +18,15 @@ export class MonitorAdvancedSearchDataprovidersComponent {
@Input() searchForm: SearchForm = {class: 'search-form', dark: false};
customFilter: SearchCustomFilter = null;
initialized: boolean = false;
showSwitchSearchLink:boolean = false;
piwikSiteId;
showSwitchSearchLink: boolean = false;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
@ -40,24 +41,19 @@ export class MonitorAdvancedSearchDataprovidersComponent {
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
if (stakeholder.type === "organization") {
let value = stakeholder.index_id;
this.customFilter = new SearchCustomFilter("Organization", "relorganizationid", value, "");
this.showSwitchSearchLink = true;
let value = stakeholder.index_id;
this.customFilter = new SearchCustomFilter("Organization", "relorganizationid", value, "");
this.showSwitchSearchLink = true;
} else if (stakeholder.type === "funder") {
let value = stakeholder.index_id+"||"+stakeholder.index_name+"||"+stakeholder.index_shortName;
this.customFilter = new SearchCustomFilter("Funder", "relfunder", value, stakeholder.name);
let value = stakeholder.index_id + "||" + stakeholder.index_name + "||" + stakeholder.index_shortName;
this.customFilter = new SearchCustomFilter("Funder", "relfunder", value, stakeholder.name);
} else if (stakeholder.type === "ri") {
let value = stakeholder.index_id+"||"+stakeholder.index_name;
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
let value = stakeholder.index_id + "||" + stakeholder.index_name;
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));
this.initialized = true;
}
}));
}
}));
}

View File

@ -3,14 +3,12 @@ import {ActivatedRoute, Router} from "@angular/router";
import {StakeholderService} from "../../../openaireLibrary/monitor/services/stakeholder.service";
import {SearchCustomFilter} from "../../../openaireLibrary/searchPages/searchUtils/searchUtils.class";
import {Subscriber} from "rxjs";
import {ConfigurationService} from "../../../openaireLibrary/utils/configuration/configuration.service";
import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSearchPage.component";
@Component({
selector: 'monitor-advanced-search-organizations',
template: `
<search-organizations *ngIf="initialized" [simpleView]="false" [showSwitchSearchLink]="false" [customFilter]="customFilter"
[piwikSiteId]="piwikSiteId" [searchForm]="searchForm">
<search-organizations *ngIf="initialized" [simpleView]="false" [showSwitchSearchLink]="false" [customFilter]="customFilter" [searchForm]="searchForm">
</search-organizations>
`
})
@ -18,10 +16,10 @@ export class MonitorAdvancedSearchOrganizationsComponent {
@Input() searchForm: SearchForm = {class: 'search-form', dark: false};
initialized: boolean = false;
customFilter: SearchCustomFilter = null;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -50,11 +48,6 @@ export class MonitorAdvancedSearchOrganizationsComponent {
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
this.customFilter.isHiddenFilter = false;
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -4,7 +4,6 @@ import {ActivatedRoute, Router} from "@angular/router";
import {StakeholderService} from "../../../openaireLibrary/monitor/services/stakeholder.service";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {ConfigurationService} from "../../../openaireLibrary/utils/configuration/configuration.service";
import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSearchPage.component";
@Component({
@ -14,7 +13,7 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
[customFilter]=customFilter [hasPrefix]="false"
[includeOnlyResultsAndFilter]="false" [showSwitchSearchLink]="showSwitchSearchLink"
[openaireLink]="'https://'+(properties.environment != 'production'?'beta.':'')+'explore.openaire.eu/search/simple/projects'"
[piwikSiteId]="piwikSiteId" [searchForm]="searchForm"
[searchForm]="searchForm"
>
</search-projects>
`
@ -26,10 +25,10 @@ export class MonitorAdvancedSearchProjectsComponent {
initialized: boolean = false;
showSwitchSearchLink:boolean = false;
properties;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -58,11 +57,6 @@ export class MonitorAdvancedSearchProjectsComponent {
let value = stakeholder.index_id+"||"+stakeholder.index_name;
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -15,7 +15,7 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
[includeOnlyResultsAndFilter]="false"
[showSwitchSearchLink]="true"
[openaireLink]="'https://'+(properties.environment != 'production'?'beta.':'')+'explore.openaire.eu/search/advanced/research-outcomes'"
[piwikSiteId]="piwikSiteId" [searchForm]="searchForm"
[searchForm]="searchForm"
></search-research-results>
`
})
@ -24,10 +24,9 @@ export class MonitorAdvancedSearchResearchResultsComponent {
initialized: boolean = false;
@Input() searchForm: SearchForm = {class: 'search-form', dark: false};
properties;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -54,11 +53,6 @@ export class MonitorAdvancedSearchResearchResultsComponent {
let value = stakeholder.index_id+"||"+stakeholder.index_name;
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -13,8 +13,7 @@ import {properties} from "../../../../environments/environment";
template: `
<search-dataproviders *ngIf="initialized"
[customFilter]=customFilter [hasPrefix]="false" [searchForm]="searchForm"
[includeOnlyResultsAndFilter]="false" [showSwitchSearchLink]="showSwitchSearchLink"
[piwikSiteId]="piwikSiteId">
[includeOnlyResultsAndFilter]="false" [showSwitchSearchLink]="showSwitchSearchLink">
</search-dataproviders>
`
})
@ -23,12 +22,11 @@ export class MonitorSearchDataprovidersComponent {
customFilter: SearchCustomFilter = null;
initialized: boolean = false;
showSwitchSearchLink: boolean = false;
piwikSiteId;
public properties: EnvProperties = properties;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
@ -54,11 +52,6 @@ export class MonitorSearchDataprovidersComponent {
} else if (stakeholder.type === "ri") {
this.navigateToError();
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -8,14 +8,13 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
@Component({
selector: 'monitor-search-organizations',
template: `
<search-organizations *ngIf="initialized" [searchForm]="searchForm" [piwikSiteId]="piwikSiteId">
<search-organizations *ngIf="initialized" [searchForm]="searchForm">
</search-organizations>
`
})
export class MonitorSearchOrganizationsComponent {
@Input() searchForm: SearchForm = {class: 'search-form', dark: false};
initialized: boolean = false;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
@ -34,11 +33,6 @@ export class MonitorSearchOrganizationsComponent {
if (params['stakeholder']) {
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -4,7 +4,6 @@ import {ActivatedRoute, Router} from "@angular/router";
import {StakeholderService} from "../../../openaireLibrary/monitor/services/stakeholder.service";
import {Subscriber} from "rxjs";
import {properties} from "../../../../environments/environment";
import {ConfigurationService} from "../../../openaireLibrary/utils/configuration/configuration.service";
import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSearchPage.component";
@Component({
@ -13,8 +12,8 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
<search-projects *ngIf="initialized"
[customFilter]=customFilter [hasPrefix]="false"
[includeOnlyResultsAndFilter]="false"
[openaireLink]="'https://'+(properties.environment != 'production'?'beta.':'')+'explore.openaire.eu/search/simple/projects'"
[piwikSiteId]="piwikSiteId" [searchForm]="searchForm">
[openaireLink]="'https://'+(properties.environment != 'production'?'beta.':'')+'explore.openaire.eu/search/simple/projects'"
[searchForm]="searchForm">
</search-projects>
`
@ -24,10 +23,9 @@ export class MonitorSearchProjectsComponent {
customFilter: SearchCustomFilter = null;
initialized: boolean = false;
properties;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -53,11 +51,6 @@ export class MonitorSearchProjectsComponent {
} else if (stakeholder.type === "ri") {
this.navigateToError();
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}

View File

@ -16,7 +16,6 @@ import {SearchForm} from "../../../openaireLibrary/searchPages/searchUtils/newSe
[showSwitchSearchLink]="true"
[searchForm]="searchForm"
[openaireLink]="'https://'+(properties.environment != 'production'?'beta.':'')+'explore.openaire.eu/search/find/research-outcomes'"
[piwikSiteId]="piwikSiteId"
></search-research-results>
`,
})
@ -25,10 +24,9 @@ export class MonitorSearchResearchResultsComponent {
customFilter: SearchCustomFilter = null;
initialized: boolean = false;
properties;
piwikSiteId;
constructor(private route: ActivatedRoute,
private router: Router,
private stakeholderService: StakeholderService, private configurationService: ConfigurationService) {
private stakeholderService: StakeholderService) {
}
subscriptions = [];
ngOnDestroy() {
@ -55,11 +53,6 @@ export class MonitorSearchResearchResultsComponent {
let value = stakeholder.index_id+"||"+stakeholder.index_name;
this.customFilter = new SearchCustomFilter("Community", "community", value, stakeholder.name);
}
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
this.piwikSiteId = portal.piwik;
}
}));
this.initialized = true;
}
}));

View File

@ -1,485 +0,0 @@
<div *ngIf="stakeholder && canEdit" class="uk-section">
<div *ngIf="numberSections">
<h5 class="uk-text-bold">Number Indicators</h5>
<div class="uk-grid uk-grid-large uk-child-width-1-1" uk-grid>
<div *ngFor="let number of numbers; let i=index">
<div class="section">
<div class="tools">
<div class="uk-flex uk-flex-middle">
<a [class.uk-disabled]="editing" class="" (click)="createSection(i, 'number')"
uk-tooltip="Create a new section">
<icon name="add" [flex]="true"></icon>
</a>
<a *ngIf="!number.defaultId" [attr.uk-tooltip]="'Delete section'"
(click)="deleteSectionOpen(number, i, 'number', 'delete')">
<icon name="close" [flex]="true"></icon>
</a>
<!-- <ng-container *ngIf="!stakeholder.defaultId">-->
<!-- <button [disabled]="editing || number.defaultId " class="md-btn md-btn-mini"-->
<!-- [title]="(number.defaultId?'Default sections cannot be deleted':'Delete all related sections')"-->
<!-- (click)="deleteSectionOpen(number, i, 'number', 'delete')"><i class="material-icons">highlight_off</i>-->
<!-- </button>-->
<!-- <button [disabled]="editing || number.defaultId " class="md-btn md-btn-mini"-->
<!-- [title]="(number.defaultId?'Default sections cannot be deleted':'Delete section and disconnect related')"-->
<!-- (click)="deleteSectionOpen(number, i, 'number', 'disconnect')"><i class="material-icons">link_off</i>-->
<!-- </button>-->
<!-- </ng-container>-->
</div>
</div>
<div *ngIf="numberSections.at(i)" class="uk-margin-medium-bottom">
<div input [formInput]="numberSections.at(i).get('title')"
(focusEmitter)="saveSection($event, numberSections.at(i), i, 'number')"
class="uk-width-1-3@m uk-width-1-1" placeholder="Title" inputClass="border-bottom"></div>
</div>
<div [id]="'number-' + number._id" class="uk-grid uk-grid-small uk-grid-match" uk-sortable="group: number" uk-grid>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="indicator" [id]="indicator._id"
[ngClass]="getNumberClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-padding-small number-card uk-position-relative">
<div *ngIf="!dragging"
class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li><a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a></li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li>
<a (click)="changeIndicatorStatus(number._id, indicator, v.value);hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li class="uk-nav-divider">
<li><a (click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a></li>
</ng-container>
</ul>
</div>
</div>
<div class="uk-text-small uk-text-truncate uk-margin-xsmall-bottom uk-margin-right">{{indicator.name}}</div>
<div class="number uk-text-small uk-text-bold">
<span *ngIf="numberResults.get(i + '-' + j)" [innerHTML]="numberResults.get(i + '-' + j) | numberRound: 2:1"></span>
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
</div>
</div>
</div>
</ng-template>
</div>
<div *ngIf="isCurator" class="uk-margin-top">
<div class="uk-grid uk-grid-small" uk-grid>
<div [ngClass]="getNumberClassBySize('small')">
<a class="uk-card uk-card-default number-card uk-padding-small uk-flex uk-flex-middle uk-link-reset" (click)="editNumberIndicatorOpen(number)">
<div class="uk-text-background uk-margin-right">
<icon name="add" [flex]="true" ratio="1.5"></icon>
</div>
<div class="uk-text-bold uk-margin-remove">
Create a number Indicator
</div>
</a>
</div>
</div>
</div>
</div>
</div>
<div>
<ng-container *ngTemplateOutlet="new_section; context:{type: 'number'}"></ng-container>
</div>
</div>
</div>
<div *ngIf="chartSections" class="uk-margin-large-top">
<h5 class="uk-text-bold">Chart Indicators</h5>
<div class="uk-grid uk-grid-large uk-child-width-1-1" uk-grid>
<div *ngFor="let chart of charts; let i=index">
<div class="section uk-margin-top uk-padding-small">
<div class="tools">
<div class="uk-flex uk-flex-middle">
<a [class.uk-disabled]="editing" class="" (click)="createSection(i)"
title="Create a new section">
<icon name="add" [flex]="true"></icon>
</a>
<a *ngIf="!chart.defaultId" [attr.uk-tooltip]="'Delete section'"
(click)="deleteSectionOpen(chart, i, 'chart', 'delete')">
<icon name="close" [flex]="true"></icon>
</a>
<!-- <ng-container *ngIf="!stakeholder.defaultId">-->
<!-- <button [disabled]="editing || chart.defaultId " class="md-btn md-btn-mini"-->
<!-- [title]="(chart.defaultId?'Default sections cannot be deleted':'Delete all related sections')"-->
<!-- (click)="deleteSectionOpen(chart, i, 'chart', 'delete')"><i class="material-icons">highlight_off</i>-->
<!-- </button>-->
<!-- <button [disabled]="editing || chart.defaultId " class="md-btn md-btn-mini"-->
<!-- [title]="(chart.defaultId?'Default sections cannot be deleted':'Delete section and disconnect related')"-->
<!-- (click)="deleteSectionOpen(chart, i, 'chart', 'disconnect')"><i class="material-icons">link_off</i>-->
<!-- </button>-->
<!-- </ng-container>-->
</div>
</div>
<div *ngIf="chartSections.at(i)"
class="uk-margin-medium-bottom">
<div input [formInput]="chartSections.at(i).get('title')"
(focusEmitter)="saveSection($event, chartSections.at(i), i)"
class="uk-width-1-3@m uk-width-1-1" placeholder="Title" inputClass="border-bottom"></div>
</div>
<div [id]="'chart-' + chart._id" class="uk-grid uk-grid-small uk-grid-match" uk-sortable="group: chart" uk-grid>
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
<div *ngIf="indicator" [id]="indicator._id" [ngClass]="getChartClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-card-body uk-position-relative">
<div *ngIf="!dragging"
class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li><a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a></li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li>
<a (click)="changeIndicatorStatus(chart._id, indicator, v.value);">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li class="uk-nav-divider">
<li><a (click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a></li>
</ng-container>
</ul>
</div>
</div>
<div>
<div *ngIf="indicator.name" class="uk-text-center uk-text-bold uk-margin-small-bottom">
{{indicator.name}}
</div>
<iframe *ngIf="!properties.disableFrameLoad && indicator.indicatorPaths[0] && indicator.indicatorPaths[0].source !=='image' &&
safeUrls.get(indicatorUtils.getFullUrl(stakeholder, indicator.indicatorPaths[0]))"
allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"
[src]="safeUrls.get(indicatorUtils.getFullUrl(stakeholder, indicator.indicatorPaths[0]))"
class="uk-width-1-1" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
[class.uk-blend-multiply]="!isFullscreen"></iframe>
<div *ngIf="properties.disableFrameLoad && indicator.indicatorPaths &&
indicator.indicatorPaths.length > 0 && indicator.indicatorPaths[0].source !=='image'">
<img class="uk-width-1-1 uk-blend-multiply" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
src="assets/chart-placeholder.png">
</div>
<div *ngIf="indicator.indicatorPaths && indicator.indicatorPaths[0] &&
indicator.indicatorPaths[0].source === 'image'">
<img class="uk-width-1-1 uk-blend-multiply" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"
[src]="indicator.indicatorPaths[0].url">
</div>
<!--<ng-container *ngTemplateOutlet="description; context: {indicator:indicator}"></ng-container>-->
</div>
</div>
</div>
</ng-template>
</div>
<div *ngIf="isCurator" class="uk-margin-top">
<div class="uk-grid uk-grid-small uk-grid-match" uk-grid>
<div [ngClass]="getChartClassBySize('small')">
<div class=" uk-card uk-card-default uk-card-body clickable" (click)="editChartIndicatorOpen(chart)">
<h6 class="uk-text-bold uk-text-center">
Create a custom indicator
</h6>
<div class="uk-text-muted uk-text-small">
Use our advance tool to create a custom Indicator that suit the needs of your funding
KPI's.
</div>
<div class="uk-flex uk-flex-center uk-text-background uk-margin-medium-top">
<icon name="add" ratio="3" [flex]="true"></icon>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div>
<ng-container *ngTemplateOutlet="new_section; context:{type: 'chart'}"></ng-container>
</div>
</div>
</div>
</div>
<modal-alert #editNumberModal
[large]="true" classTitle="uk-background-primary uk-light"
(alertOutput)="saveIndicator()"
[okDisabled]="numberIndicatorFb && (numberIndicatorFb.invalid || numberIndicatorFb.pristine)">
<div *ngIf="editing" class="uk-position-relative uk-height-large">
<loading class="uk-position-center"></loading>
</div>
<div [class.uk-hidden]="editing" class="uk-padding-small">
<div *ngIf="numberIndicatorFb" class="uk-grid" [formGroup]="numberIndicatorFb" uk-grid>
<div input class="uk-width-1-1" [formInput]="numberIndicatorFb.get('name')" placeholder="Title"></div>
<div *ngIf="stakeholder.defaultId != '-1' && ( (indicator.description && indicator.description.length > 0) || !stakeholder.defaultId)"
input class="uk-width-1-1" [formInput]="numberIndicatorFb.get('description')" placeholder="Profile description" type="textarea">
</div>
<div input class="uk-width-1-1" *ngIf="stakeholder.defaultId" [formInput]="numberIndicatorFb.get('additionalDescription')"
placeholder="Description" type="textarea">
</div>
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('visibility')"
placeholder="Visibility" [options]="stakeholderUtils.visibility" type="select">
</div>
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('width')"
placeholder="Number Size" [options]="indicatorUtils.indicatorSizes" type="select">
</div>
<div *ngIf="numberIndicatorPaths" formArrayName="indicatorPaths">
<div *ngFor="let indicatorPath of numberIndicatorPaths.controls; let i=index" [formGroupName]="i">
<div class="uk-grid" uk-grid>
<div class="uk-width-1-1">
<div class="uk-grid" uk-grid>
<div class="uk-width-1-1 uk-flex uk-flex-middle">
<div input class="uk-width-expand" [formInput]="indicatorPath.get('url')" placeholder="Number URL">
<div *ngIf="urlParameterizedMessage" warning>{{urlParameterizedMessage}}</div>
</div>
<div class='uk-padding-small'>
<a class="uk-link-reset" (click)="copyToClipboard(indicatorPath.get('url').value)"><icon [flex]="true" name="content_copy"></icon></a>
</div>
</div>
<div *ngIf="showCheckForSchemaEnhancements" class="uk-width-1-1">
<div class="uk-alert uk-alert-warning">
There are schema enhancements that can be applied in this query.<a
(click)="indicatorPath.get('url').setValue(indicatorUtils.applySchemaEnhancements(indicatorPath.get('url').value)); indicatorPath.get('url').markAsDirty()">Apply
now</a>
</div>
</div>
<div class="uk-width-1-1">
<div input [formInput]="indicatorPath.get('source')" placeholder="Source"
[options]="isAdministrator?indicatorUtils.allSourceTypes:indicatorUtils.sourceTypes" type="select">
</div>
</div>
</div>
</div>
<div formArrayName="jsonPath" class="uk-width-1-1">
<h6 class="uk-text-bold uk-margin-remove-bottom">
<span>JSON Path</span>
</h6>
<div *ngIf="numberIndicatorPaths.at(i).get('result').invalid && numberIndicatorPaths.at(i).get('result').errors.required">
<div class="uk-text-danger uk-text-small">
This JSON path is not valid or the result has not been calculated yet.
Please press calculate on box below to see the result.
</div>
</div>
<div class="uk-grid uk-child-width-1-3@m uk-child-width-1-1 uk-margin-top uk-flex-middle" uk-grid>
<div *ngFor="let jsonPath of getJsonPath(i).controls; let j=index" class="uk-flex uk-flex-middle">
<div input class="uk-width-1-1" [formInput]="jsonPath" [placeholder]="'Level ' + +(j + 1)"></div>
<a [class.uk-invisible]="getJsonPath(i).length === 1 || numberIndicatorFb.get('defaultId').value"
class="uk-margin-small-left uk-text-danger"
[class.uk-disabled]="getJsonPath(i).disabled"
(click)="removeJsonPath(i, j)">
<icon name="close"></icon>
</a>
<span [class.uk-invisible]="getJsonPath(i).disabled || j === (getJsonPath(i).controls.length - 1)" class="uk-text-center uk-margin-small-left">
<icon name="east"></icon>
</span>
</div>
<div *ngIf="indicator.defaultId === null">
<button class="uk-icon-button uk-button-primary" (click)="addJsonPath(i)">
<icon name="add" [flex]="true"></icon>
</button>
</div>
</div>
</div>
<div class="uk-width-1-1 uk-flex uk-flex-center">
<div class="uk-flex uk-position-relative">
<span class="uk-padding number number-preview uk-flex uk-flex-column uk-flex-center uk-text-center">
<span *ngIf="numberIndicatorPaths.at(i).get('result').valid && numberIndicatorPaths.at(i).get('result').value !== 0">
{{numberIndicatorPaths.at(i).get('result').value | number}}
</span>
<span *ngIf="numberIndicatorPaths.at(i).get('result').valid && numberIndicatorPaths.at(i).get('result').value === 0">
--
</span>
</span>
<div *ngIf="numberIndicatorPaths.at(i).get('result').invalid"
class="uk-width-1-1 uk-height-1-1 refresh-indicator">
<div class="uk-position-relative uk-height-1-1">
<a class="uk-position-center uk-text-center uk-text-small uk-link-reset"
[class.uk-disabled]="numberIndicatorPaths.at(i).get('url').invalid"
(click)="validateJsonPath(i, true)">
<div>
<icon name="refresh"></icon>
</div>
<span *ngIf="numberIndicatorPaths.at(i).get('result').errors.required">Calculate</span>
<span *ngIf="numberIndicatorPaths.at(i).get('result').errors.validating">Calculating...</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div #editNumberNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
</div>
</modal-alert>
<modal-alert #editChartModal [large]="true" (alertOutput)="saveIndicator()" classTitle="uk-background-primary uk-light"
[okDisabled]="chartIndicatorFb && (chartIndicatorFb.invalid || chartIndicatorFb.pristine)">
<div *ngIf="editing" class="uk-position-relative uk-height-large">
<loading class="uk-position-center"></loading>
</div>
<div [class.uk-hidden]="editing" class="uk-padding-small">
<div *ngIf="chartIndicatorFb" [formGroup]="chartIndicatorFb" class="uk-grid" uk-grid>
<div input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('name')" placeholder="Title"></div>
<div *ngIf="stakeholder.defaultId != '-1' && ((indicator.description && indicator.description.length > 0) || !stakeholder.defaultId)"
input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('description')" placeholder="Default Description" type="textarea">
</div>
<div *ngIf="stakeholder.defaultId" input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('additionalDescription')"
placeholder="Description" type="textarea">
</div>
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('visibility')"
placeholder="Status" [options]="stakeholderUtils.visibility" type="select">
</div>
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('width')" placeholder="Chart width"
[options]="indicatorUtils.indicatorSizes" type="select">
</div>
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('height')" placeholder="Chart height"
[options]="indicatorUtils.indicatorSizes" type="select">
</div>
<div *ngIf="chartIndicatorPaths" formArrayName="indicatorPaths" class="uk-width-1-1">
<div *ngFor="let indicatorPath of chartIndicatorPaths.controls; let i=index;"
[formGroupName]="i" class="uk-grid" uk-grid>
<div class="uk-width-1-1 uk-flex uk-flex-middle">
<div input class="uk-width-expand" [title]="indicatorPath.get('url').disabled?'Default chart URLs cannot change':''"
[formInput]="indicatorPath.get('url')" placeholder="Chart URL">
<div *ngIf="urlParameterizedMessage" warning>{{urlParameterizedMessage}}</div>
</div>
<div class='uk-padding-small'>
<a class="uk-link-reset" (click)="copyToClipboard(indicatorPath.get('url').value)"><icon [flex]="true" name="content_copy"></icon></a>
</div>
</div>
<div *ngIf="showCheckForSchemaEnhancements" class=" uk-width-1-1 ">
<div class="uk-alert uk-alert-warning">
There are schema enhancements that can be applied in this query. <a
(click)="indicatorPath.get('url').setValue(indicatorUtils.applySchemaEnhancements(indicatorPath.get('url').value)); indicatorPath.get('url').markAsDirty()">Apply
now</a>
</div>
</div>
<div class="uk-width-1-1" formArrayName="parameters">
<div class="uk-grid" uk-grid>
<div *ngIf="getParameter(i, 'title')" input class="uk-width-1-1" [formInput]="getParameter(i, 'title').get('value')"
placeholder="Chart Title"></div>
<div *ngIf="getParameter(i, 'subtitle')" input class="uk-width-1-1" placeholder="Chart Subtitle" [formInput]="getParameter(i, 'subtitle').get('value')" label="Chart Subtitle"></div>
<div *ngIf="!getParameter(i, 'type')" input class="uk-width-1-3@s" [formInput]="indicatorPath.get('type')" placeholder="Chart Type"
[options]="(indicatorPath.get('type').value == 'table' && getParameter(i, 'data_title_0'))?indicatorUtils.getChartTypes(indicatorPath.get('type').value):indicatorUtils.allChartTypes"
type="select"></div>
<div *ngIf="getParameter(i, 'type')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'type').get('value')" placeholder="Chart Type"
[options]="indicatorUtils.getChartTypes(getParameter(i, 'type').get('value').value)" type="select"></div>
<div *ngIf="getParameter(i, 'xAxisTitle')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'xAxisTitle').get('value')"
placeholder="X-Axis Title"></div>
<div *ngIf="getParameter(i, 'yAxisTitle')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'yAxisTitle').get('value')"
placeholder="Y-Axis Title"></div>
<div *ngIf="getParameter(i, 'data_title_0')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'data_title_0').get('value')"
placeholder="Data Title"></div>
<div *ngIf="getParameter(i, 'data_title_1')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'data_title_1').get('value')"
placeholder="Data Title"></div>
<div *ngIf="getParameter(i, 'start_year')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'start_year').get('value')"
placeholder="Year (From)"></div>
<div *ngIf="getParameter(i, 'end_year')" input class="uk-width-1-3@s" [formInput]="getParameter(i, 'end_year').get('value')"
placeholder="Year (To)"></div>
</div>
</div>
<div *ngIf="indicator && indicator.indicatorPaths[i] && indicator.indicatorPaths[i].safeResourceUrl"
class="uk-margin-medium-top uk-position-relative uk-width-1-1 uk-flex uk-flex-center">
<div *ngIf="(hasDifference(i)) && !indicatorPath.invalid"
class="uk-width-1-1 uk-height-large refresh-indicator">
<div class="uk-position-relative uk-height-1-1">
<a class="uk-position-center uk-text-center uk-link-reset" (click)="refreshIndicator()">
<div>
<icon name="refresh"></icon>
</div>
<span>Click to refresh the graph view</span>
</a>
</div>
</div>
<iframe *ngIf="indicator.indicatorPaths[i].source !== 'image'" [class.uk-blend-multiply]="!isFullscreen"
[src]="indicator.indicatorPaths[i].safeResourceUrl" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"
class="uk-width-1-1 uk-height-large"></iframe>
<!-- <div *ngIf="properties.disableFrameLoad && indicator.indicatorPaths[i].source !== 'image'" class="uk-alert uk-alert-danger uk-text-center">I frames-->
<!-- preview is disabled</div>-->
<div *ngIf="indicator.indicatorPaths[i].source === 'image'">
<img class="uk-width-1-1 uk-height-large uk-blend-multiply" [src]="indicator.indicatorPaths[i].url">
</div>
</div>
</div>
</div>
</div>
<div #editChartNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
</div>
</modal-alert>
<modal-alert #deleteModal (alertOutput)="deleteIndicator()" [overflowBody]="false" classTitle="uk-background-primary uk-light">
<div [class.uk-invisible]="editing" class="uk-position-relative">
<div *ngIf="editing">
<loading class="uk-position-center"></loading>
</div>
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
"{{indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title?indicator.indicatorPaths[0].parameters.title:'')}}"</span> indicator permanently.
<div *ngIf="indicatorChildrenActionOnDelete == 'delete'" class="uk-text-bold">
Indicators of all profiles based on this default indicator, will be deleted as well.
</div>
<!-- <span *ngIf="indicatorChildrenActionOnDelete == 'disconnect'" class="uk-text-bold">-->
<!-- Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.-->
<!-- </span>-->
Are you sure you want to proceed?
<div #deleteNotify notify-form class="uk-width-1-1 uk-margin-medium-top"></div>
</div>
</modal-alert>
<!--<modal-alert #deleteAllModal (alertOutput)="deleteIndicator('delete')">
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
"{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently.
<span class="uk-text-bold">Indicators of all profiles based on this default indicator, will be deleted as well.</span>
Are you sure you want to proceed?
</modal-alert>
<modal-alert #deleteAndDisconnectModal (alertOutput)="deleteIndicator('disconnect')">
You are about to delete <span class="uk-text-bold" *ngIf="indicator && index !== -1">
"{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}"</span> indicator permanently.
<span class="uk-text-bold">Indicators of all profiles based on this default indicator, will not be marked as copied from default anymore.</span>
Are you sure you want to proceed?
</modal-alert>-->
<modal-alert #deleteSectionModal (alertOutput)="deleteSection()" [overflowBody]="false" classTitle="uk-background-primary uk-light">
<div [class.uk-invisible]="editing" class="uk-position-relative">
<div *ngIf="editing">
<loading class="uk-position-center"></loading>
</div>
You are about to delete this section and its indicators permanently.
<div *ngIf="sectionChildrenActionOnDelete == 'delete' && !stakeholder.defaultId" class="uk-text-bold">
Sections of all profiles based on this default section and their contents, will be deleted as well.
</div>
<!-- <span *ngIf="sectionChildrenActionOnDelete == 'disconnect'" class="uk-text-bold">-->
<!-- Sections of all profiles based on this default section and their contents, will not be marked as copied from default anymore.-->
<!-- </span>-->
Are you sure you want to proceed?
</div>
</modal-alert>
<!--<modal-alert #deleteNumberSectionModal (alertOutput)="deleteSection('number')">
You are about to delete this section and its indicators permanently.
Are you sure you want to proceed?
</modal-alert>
<modal-alert #deleteChartSectionModal (alertOutput)="deleteSection()">
You are about to delete this section and its indicators permanently.
Are you sure you want to proceed?
</modal-alert>-->
<ng-template #new_section let-type="type">
<div class="section">
<div class="uk-flex uk-flex-center" (click)="createSection(-1, type)">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">New section</span>
</button>
</div>
</div>
</ng-template>

View File

@ -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;
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -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 {
}

View File

@ -1,379 +0,0 @@
<aside *ngIf="stakeholder" id="sidebar_main">
<div sidebar-content>
<div class="back">
<a [routerLink]="'/admin/' + stakeholder.alias" class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon name="west" [flex]="true" ratio="1.3"></icon>
</div>
<span class="uk-width-expand uk-text-truncate uk-margin-left hide-on-close">Indicators</span>
</a>
</div>
<div class="menu_section uk-margin-large-top">
<ul class="uk-list uk-nav uk-nav-default uk-nav-parent-icon" transition-group [id]="'topics'"
uk-nav="duration: 400">
<li *ngFor="let topic of stakeholder.topics; let i=index" class="uk-parent" [class.uk-active]="topicIndex === i"
transition-group-item>
<a [routerLink]="'/admin/'+stakeholder.alias + '/indicators/' + topic.alias"
[title]="topic.name" class="uk-visible-toggle uk-flex uk-flex-middle">
<div *ngIf="topic.icon" class="uk-width-auto">
<icon class="menu-icon" [svg]="topic.icon" ratio="0.9" [flex]="true"></icon>
</div>
<span [class.hide-on-close]="topic.icon"
class="uk-width-expand uk-text-truncate uk-margin-small-left">
{{topic.name}}
</span>
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="topicIndex !== i"
(click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(topic.visibility)"
ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editTopicOpen(i); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="edit" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Edit</span>
</div>
</a>
</li>
<li *ngIf="i > 0 || i < stakeholder.topics.length - 1" class="uk-nav-divider"></li>
<li *ngIf="i > 0">
<a (click)="hide(element);moveTopic(i)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="north" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Up</span>
</div>
</a>
</li>
<li *ngIf="i < stakeholder.topics.length - 1">
<a (click)="hide(element);moveTopic(i, i + 1)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="south" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Down</span>
</div>
</a>
</li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="topic.visibility === v.value">
<a (click)="openVisibilityModal(i, v.value, 'topic'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="topic.visibility === v.value" [flex]="true" name="done"
class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<ng-container *ngIf="!topic.defaultId && isCurator">
<li class="uk-nav-divider">
<li>
<a (click)="deleteTopicOpen(i, 'delete'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="delete" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Delete</span>
</div>
</a>
<!--<ng-container *ngIf="!stakeholder.defaultId">
<a (click)="deleteTopicOpen(i, 'delete'); hide(element)">Delete from all profiles</a>
<a (click)="deleteTopicOpen(i, 'disconnect'); hide(element)">Delete and disconnect from all profiles</a>
</ng-container>-->
</li>
</ng-container>
</ul>
</div>
</span>
</a>
<ul *ngIf="isBrowser || topicIndex === i" class="uk-nav-sub" [id]="'categories-' + i.toString()"
transition-group>
<li *ngFor="let category of topic.categories; let j=index" transition-group-item class="uk-visible-toggle"
[class.uk-active]="categoryIndex == j">
<a (click)="chooseCategory(j)" [title]="category.name">
<div class="uk-flex uk-flex-middle uk-width-1-1">
<span class="uk-width-expand uk-text-truncate">{{category.name}}</span>
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="categoryIndex !== j"
(click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(category.visibility)"
ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editCategoryOpen(j); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="edit" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Edit</span>
</div>
</a>
</li>
<li *ngIf="j > 0 || j < stakeholder.topics[topicIndex].categories.length - 1"
class="uk-nav-divider"></li>
<li *ngIf="j > 0">
<a (click)="hide(element);moveCategory(j)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="north" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Up</span>
</div>
</a>
</li>
<li *ngIf="j < stakeholder.topics[topicIndex].categories.length - 1">
<a (click)="hide(element);moveCategory(j, j + 1)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="south" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Down</span>
</div>
</a>
</li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="category.visibility === v.value">
<a (click)="openVisibilityModal(j, v.value, 'category'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="category.visibility === v.value" [flex]="true" name="done"
class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<ng-container *ngIf="!category.defaultId && isCurator">
<li class="uk-nav-divider">
<li>
<a (click)="deleteCategoryOpen(j, 'delete'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="delete" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Delete</span>
</div>
</a>
</li>
</ng-container>
</ul>
</div>
</span>
</div>
</a>
</li>
<li *ngIf="isCurator">
<a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="hide-on-close">Create new category</span>
</a>
</li>
</ul>
</li>
<li *ngIf="isCurator" class="hide-on-close">
<a (click)="editTopicOpen(-1); $event.preventDefault()">
<div class="uk-flex uk-flex-middle">
<div class="uk-width-auto">
<icon class="menu-icon" name="add" [flex]="true"></icon>
</div>
<span class="uk-width-expand uk-text-truncate uk-margin-small-left hide-on-close">Create new topic</span>
</div>
</a>
</li>
</ul>
</div>
</div>
</aside>
<div #pageContent *ngIf="stakeholder && filters" page-content>
<div actions>
<div *ngIf="stakeholder.topics.length > 0" class="uk-flex uk-flex-center uk-margin-medium-top uk-flex-right@m uk-width-1-1">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle">
<icon name="visibility" [flex]="true"></icon>
<span class="uk-margin-small-left uk-margin-small-right">Preview</span>
<icon name="expand_more" [flex]="true"></icon>
</button>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false">
<ul class="uk-nav uk-dropdown-nav">
<li><a target="_blank"
[routerLink]="'/' + stakeholder.alias + '/' + stakeholder.topics[topicIndex].alias"
[queryParams]="{view: 'PUBLIC'}"
(click)="hide(element)">Public view</a>
</li>
<li><a target="_blank" [routerLink]="'/' + stakeholder.alias + '/' +
stakeholder.topics[topicIndex].alias"
[queryParams]="{view: 'RESTRICTED'}"
(click)="hide(element)">Restricted view</a>
</li>
<!--<li class="disabled"><a class="uk-disabled uk-text-muted"
uk-tooltip="Note: available only in administration dashboard"
(click)="hide(element)">Private view</a>
</li>-->
</ul>
</div>
</div>
<ul *ngIf="stakeholder.topics.length > 0 && stakeholder.topics[topicIndex].categories.length > 0 && stakeholder.topics[topicIndex].categories[categoryIndex]"
transition-group class="uk-tab uk-margin-xsmall-top" [id]="'subCategories'">
<ng-template ngFor [ngForOf]=" stakeholder.topics[topicIndex].categories[categoryIndex].subCategories"
let-subCategory let-i="index">
<li class="uk-visible-toggle uk-flex" [class.uk-active]="subCategoryIndex === i" transition-group-item>
<a (click)="chooseSubcategory(i)">
<span class="uk-text-uppercase">{{subCategory.name}}</span>
</a>
<span class="uk-flex uk-flex-column uk-flex-center uk-margin-small-left"
[class.uk-invisible-hover]="subCategoryIndex !== i"
(click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(subCategory.visibility)"
ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon>
</a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; container: body">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editSubCategoryOpen(i); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="edit" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Edit</span>
</div>
</a>
</li>
<li *ngIf="i > 0 || i < stakeholder.topics[topicIndex].categories[categoryIndex].subCategories.length - 1"
class="uk-nav-divider"></li>
<li *ngIf="i > 0">
<a (click)="hide(element);moveSubCategory(i)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="west" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Left</span>
</div>
</a>
</li>
<li *ngIf="i < stakeholder.topics[topicIndex].categories[categoryIndex].subCategories.length - 1">
<a (click)="hide(element);moveSubCategory(i, i + 1)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="east" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Move Right</span>
</div>
</a>
</li>
<li class="uk-nav-divider"></li>
<li *ngIf="indicators">
<a (click)=" indicators.exportIndicators(i);hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="download" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Export indicators</span>
</div>
</a>
</li>
<li *ngIf="indicators">
<a (click)="file.value = ''; this.index=i; file.click(); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="upload" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Import indicators</span>
</div>
</a>
</li>
<li class="uk-nav-divider"></li>
</ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v>
<li [class.uk-active]="subCategory.visibility === v.value">
<a (click)="openVisibilityModal(i, v.value, 'subcategory'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
<icon *ngIf="subCategory.visibility === v.value" [flex]="true" name="done"
class="uk-text-secondary" ratio="0.8"></icon>
</div>
</a>
</li>
</ng-template>
<ng-container *ngIf="!subCategory.defaultId && isCurator">
<li class="uk-nav-divider">
<li>
<a (click)="deleteSubcategoryOpen(i, 'delete'); hide(element)">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" name="delete" ratio="0.6"></icon>
<span class="uk-margin-small-left uk-width-expand">Delete</span>
</div>
</a>
</li>
</ng-container>
</ul>
</div>
</span>
</li>
</ng-template>
<li *ngIf="isCurator">
<a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-text-uppercase">Create new subcategory</span>
</a>
</li>
</ul>
</div>
<div inner>
<input #file id="import-file" type="file" class="uk-hidden"
(change)="indicators.fileChangeEvent($event, this.index)"/>
<indicators #indicators [topicIndex]="topicIndex" [categoryIndex]="categoryIndex"
[subcategoryIndex]="subCategoryIndex" [user]="user"
[stakeholder]="stakeholder" [changed]="change.asObservable()"></indicators>
</div>
</div>
<modal-alert #deleteModal classTitle="uk-background-primary uk-light" (alertOutput)="deleteElement()"
[overflowBody]="false">
<div [class.uk-invisible]="loading" class="uk-position-relative">
<div *ngIf="loading">
<loading class="uk-position-center"></loading>
</div>
You are about to delete <span class="uk-text-bold" *ngIf="element">"{{element.name}}"</span> {{type}} permanently.
<div *ngIf="elementChildrenActionOnDelete == 'delete'" class="uk-text-bold">
{{getPluralTypeName()}} of all profiles based on this default {{type}}, will be deleted as well.
</div>
Are you sure you want to proceed?
</div>
</modal-alert>
<modal-alert #editModal classTitle="uk-background-primary uk-light" (alertOutput)="saveElement()"
[okDisabled]="form && (form.invalid || form.pristine)" [large]="true">
<div *ngIf="loading" class="uk-position-relative uk-height-large">
<loading class="uk-position-center"></loading>
</div>
<div *ngIf="form" [class.uk-hidden]="loading"
class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="form" uk-grid>
<div input [formInput]="form.get('name')" class="uk-width-1-2@m" placeholder="Title"></div>
<div input [formInput]="form.get('visibility')" class="uk-width-1-2@m" placeholder="Status"
[options]="stakeholderUtils.visibility" type="select"></div>
<div input [formInput]="form.get('description')" placeholder="Description" type="textarea" rows="4"></div>
<div *ngIf="form.get('icon')" input [formInput]="form.get('icon')" placeholder="Icon(SVG)" type="textarea"></div>
</div>
</modal-alert>
<modal-alert #visibilityModal [large]="false" classTitle="uk-background-primary uk-light">
<div class="">
You have the option to change the visibility status of your {{type}}, with or without applying the changed status to
its contents.
</div>
<div class="uk-flex uk-flex-center uk-margin-medium-top uk-margin-medium-bottom">
<button class="uk-button uk-button-primary" (click)="changeElementStatus()">
Change {{type}} status
</button>
</div>
<div class="uk-flex uk-flex-center uk-margin-medium-bottom">
<button class="uk-button uk-button-primary" (click)="changeElementStatus(true)">
Change {{type}} and its contents' status
</button>
</div>
<div class="uk-text-small">
<p class="uk-text-bold uk-text-uppercase uk-margin-remove">Note:</p>
<div>
<span class="uk-text-bold uk-text-italic">The status of the {{type}} prevails the status of its contents.</span>
For example, if a {{type}}'s status is private, while it has
<span *ngIf="type == 'topic'">a category, subcategory or an indicator</span>
<span *ngIf="type == 'category'">a subcategory or an indicator</span>
<span *ngIf="type == 'subcategory'">an indicator</span>
that is public, the private status of the {{type}} dominates.
</div>
</div>
</modal-alert>

View File

@ -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<void> = new Subject<void>();
/**
* Current topic
**/
public topicIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(0);
public topicIndex: number = 0;
/**
* Current category
*/
public categoryIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(0);
public categoryIndex: number = 0;
/**
* Current Subcategory
*/
public subCategoryIndexSubject: BehaviorSubject<number> = new BehaviorSubject<number>(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<TransitionGroupComponent>;
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 <b>successfully changed</b> to ' + returnedElement.visibility.toLowerCase());
} else {
element.visibility = returnedElement.visibility;
NotificationHandler.rise(StringUtils.capitalize(this.type) + ' has been <b>successfully changed</b> 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();
}
}

View File

@ -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]);
}
}

View File

@ -1,51 +0,0 @@
import {Injectable} from '@angular/core';
import {
ActivatedRouteSnapshot,
CanActivate,
CanActivateChild,
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 implements CanActivate, CanActivateChild {
constructor(private router: Router,
private stakeholderService: StakeholderService,
private userManagementService: UserManagementService) {
}
check(path: string, alias: string): Observable<boolean> | 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<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.check(state.url, route.params.stakeholder);
}
canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.check(state.url, childRoute.params.stakeholder);
}
}

View File

@ -1,959 +0,0 @@
import {
ChartHelper, FilterType,
Indicator, IndicatorFilterUtils,
IndicatorPath, IndicatorPathType, IndicatorType,
SourceType,
Stakeholder,
SubCategory,
Topic, Visibility,
StakeholderEntities
} 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'},
];
visibilityIcon: Map<Visibility, string> = new Map<Visibility, string> ([
["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[]): Stakeholder {
funder.topics = HelperFunctions.copy(defaultTopics);
for (let topic of funder.topics) {
// console.log('id:' + topic._id);
topic.defaultId = topic._id;
topic._id = null;
// console.log('defaultId:' + topic.defaultId);
for (let category of topic.categories) {
category.defaultId = category._id;
category._id = null;
let subTokeep: SubCategory[] = [];
for (let subCategory of category.subCategories) {
subCategory.defaultId = subCategory._id;
subCategory._id = null;
subTokeep.push(subCategory);
for (let section of subCategory.charts) {
let chartsTokeep: Indicator[] = [];
section.defaultId = section._id;
section.stakeholderAlias = funder.alias;
section._id = null;
for (let indicator of section.indicators) {
indicator.defaultId = indicator._id;
indicator._id = null;
chartsTokeep.push(indicator);
for (let indicatorPath of indicator.indicatorPaths) {
if (indicatorPath.parameters) {
Object.keys(indicatorPath.parameters).forEach(key => {
//TODO check before delete
/*if (indicatorPath.parameters[key].indexOf("_funder_name_") != -1) {
indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_name_", funder.index_name);
} else if (indicatorPath.parameters[key].indexOf("_funder_id_") != -1) {
indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_id_", funder.index_id);
} else if (indicatorPath.parameters[key].indexOf("_fsn_") != -1) {
indicatorPath.parameters[key] = indicatorPath.parameters[key].toString().replace("_fsn_", funder.index_shortName.toLowerCase());
}*/
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 = section._id;
section.stakeholderAlias = funder.alias;
section._id = null;
for(let indicator of section.indicators) {
indicator.defaultId = indicator._id;
indicator._id = null;
for (let indicatorPath of indicator.indicatorPaths) {
/* indicatorPath.url = indicatorPath.url.replace("index_id", encodeURIComponent(funder.index_id));
indicatorPath.url = indicatorPath.url.replace("index_name", encodeURIComponent(funder.index_name));
indicatorPath.url = indicatorPath.url.replace("index_shortName", encodeURIComponent(funder.index_shortName));*/
// if(indicatorPath.parameters) {
// indicatorPath.parameters.forEach((value: string, key: string) => {
// if (value.indexOf("_funder_name_")!=-1) {
// indicatorPath.parameters.set(key,value.toString().replace("_funder_name_", funder.index_name));
// }else if (value.indexOf("_fsn_")!=-1) {
// indicatorPath.parameters.set(key,value.toString().replace("_fsn_", funder.index_shortName.toLowerCase()));
// }
// });
// }
}
}
}
}
category.subCategories = subTokeep;
}
}
//console.log (funder);
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'}
];
sourceTypes: Option[] = [
{value: 'stats-tool', label: 'Statistics tool'}
];
isPublic: Option[] = [
{icon: 'public', value: true, label: 'Public'},
{icon: 'lock', value: false, label: 'Private'},
];
isActive: Option[] = [
{icon: 'brightness_1', iconClass: '', value: true, label: 'Active'},
{icon: 'brightness_1', value: false, label: 'Inactive'},
];
chartTypesIcons: Map<string, string> = new Map([
['pie', 'pie_chart'],
['table', 'table_chart'],
['line', 'show_chart'],
['column', 'bar_chart'],
['bar', 'notes'],
['other', 'perm_media']
]);
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;
}
}
isPublicIcon: Map<boolean, string> = new Map([
[true, 'public'],
[false, 'lock']
]);
isActiveIcon: string = 'brightness_1';
ignoredParameters = ['index_name','index_id','index_shortName'];
parametersValidators: Map<string, any> = new Map<string, any>([
['start_year', [Validators.required, Validators.pattern('^\\d+$')]],
['end_year', [Validators.required, Validators.pattern('^\\d+$')]]
]);
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 (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(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) !=- 1){
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id))
}
if(indicatorPath.url.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) !=- 1){
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name))
}
if(indicatorPath.url.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 (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);
// console.debug("Field Params length:" + paramFields.length)
// console.debug(paramFields)
// console.debug("Parameters length:" + queries["query"]["parameters"].length)
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);
}
}
}
// console.debug(queries["query"])
// 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]);
}
}
}
// console.debug(values);
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;
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);
// console.debug(indicatorPath);
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;
}
// console.debug(indicatorPath.parameters);
// console.debug(indicatorPath.chartObject);
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"]["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"]["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"]["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));
}
console.debug(changes);
console.debug(url);
return url;
}
}

View File

@ -1,71 +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";
@Injectable({
providedIn: 'root'
})
export class StatisticsService {
numberSources: Map<SourceType, string[]> = new Map<SourceType, string[]>();
chartSources: Map<SourceType, string[]> = new Map<SourceType, string[]>();
constructor(private http:HttpClient) {
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;
}
getNumbers(source: SourceType, url: string): Observable<any> {
if(source !== null) {
return this.http.get<any>(this.numberSources.get(source)[0] + url);
} else {
return this.http.get<any>(url);
}
}
getChartUrl(source: SourceType, url: string): string {
return this.chartSources.get(source)[0] + url;
}
getNumberUrl(source: string, 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;
}
}

@ -1 +1 @@
Subproject commit ca209a54baaa2d9e0004613a68088fdcf4bee43a
Subproject commit 186e4bf732f96459a1e22b44ba172f08f0c11d48

View File

@ -4,6 +4,7 @@
@import (multiple) "~src/assets/common-assets/less/general";
@import (multiple) "~src/assets/common-assets/less/user";
@import (multiple) "~src/assets/common-assets/less/dashboard";
@import (multiple) "~src/assets/common-assets/less/indicators";
@import (multiple) "~src/assets/common-assets/less/landing";
@monitor-dashboard-background: #F3F3F3;

@ -1 +1 @@
Subproject commit aa1e6c9df390a4ba0919b5f8591374f7eec75089
Subproject commit e721fef20399f15c9dc9bee28b3d7e9b92db2021

View File

@ -1,124 +1,20 @@
import {EnvProperties} from "../app/openaireLibrary/utils/properties/env-properties";
import {common, commonBeta} from "../app/openaireLibrary/utils/properties/environments/environment";
export let properties: EnvProperties = {
environment: "beta",
let props: EnvProperties = {
dashboard: 'monitor',
isDashboard: true,
enablePiwikTrack: true,
useCache: false,
useLongCache: true,
showContent: true,
framesAPIURL: "https://beta.openaire.eu/stats3/",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://beta.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://beta.services.openaire.eu/stats-tool/",
useNewStatistisTool: true,
monitorStatsFrameUrl:"https://beta.services.openaire.eu/stats-tool/",
useOldStatisticsSchema: true,
claimsAPIURL: "https://beta.services.openaire.eu/claims/rest/claimsService/",
searchAPIURLLAst: "https://beta.services.openaire.eu/search/v2/api/",
searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources",
openCitationsAPIURL: "https://services.openaire.eu/opencitations/getCitations?id=",
csvAPIURL: "https://beta.services.openaire.eu/search/v2/api/reports",
searchCrossrefAPIURL: "https://api.crossref.org/works",
searchDataciteAPIURL: "https://api.datacite.org/works",
searchOrcidURL: "https://pub.orcid.org/v2.1/",
orcidURL: "https://orcid.org/",
doiURL: "https://doi.org/",
pmcURL: "http://europepmc.org/articles/",
pmidURL: "https://www.ncbi.nlm.nih.gov/pubmed/",
handleURL: "http://hdl.handle.net/",
cordisURL: "http://cordis.europa.eu/projects/",
openDoarURL: "http://v2.sherpa.ac.uk/id/repository/",
r3DataURL: "http://service.re3data.org/repository/",
fairSharingURL: "https://fairsharing.org/",
eoscMarketplaceURL: "https://marketplace.eosc-portal.eu/services/",
sherpaURL: 'http://sherpa.ac.uk/romeo/issn/',
sherpaURLSuffix: '/',
zenodo: "https://zenodo.org/",
zenodoCommunities: "https://zenodo.org/api/communities/",
openAccess: "https://www.openaire.eu/support/faq#article-id-234",
openAccessRepo: "https://www.openaire.eu/support/faq#article-id-310",
fp7Guidlines: "https://www.openaire.eu/open-access-in-fp7-seventh-research-framework-programme",
h2020Guidlines: "https://www.openaire.eu/oa-publications/h2020/open-access-in-horizon-2020",
ercGuidlines: "http://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_2014.pdf",
helpdesk: 'https://www.openaire.eu/support/helpdesk',
helpdeskEmail: 'helpdesk@openaire.eu',
utilsService: "https://demo.openaire.eu/utils-service",
vocabulariesAPI: "https://beta.services.openaire.eu/provision/mvc/vocabularies/",
piwikBaseUrl: "https://analytics.openaire.eu/piwik.php?idsite=",
piwikSiteId: "298",
loginUrl: "https://beta.services.openaire.eu/login-service/openid_connect_login",
userInfoUrl: "https://beta.services.openaire.eu/login-service/userInfo",
registryUrl: 'https://beta.services.openaire.eu/uoa-user-management/api/registry/',
logoutUrl: "https://beta.services.openaire.eu/login-service/openid_logout",
cookieDomain: ".openaire.eu",
feedbackmail: "feedback@openaire.eu",
cacheUrl: "https://demo.openaire.eu/cache/get?url=",
monitorServiceAPIURL: "https://beta.services.openaire.eu/uoa-monitor-service",
adminToolsAPIURL: "https://beta.services.openaire.eu/uoa-monitor-service/",
notificationsAPIURL: "https://beta.services.openaire.eu/uoa-monitor-service/notification/",
adminToolsCommunity: "monitor",
useHelpTexts:true,
datasourcesAPI: "https://beta.services.openaire.eu/openaire/ds/search/",
contextsAPI: "https://beta.services.openaire.eu/openaire/context",
communityAPI: "https://beta.services.openaire.eu/openaire/community/",
communitiesAPI: "https://beta.services.openaire.eu/openaire/community/communities",
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
baseLink: "/dashboard",
domain: "https://beta.monitor.openaire.eu",
searchLinkToResult: "/search/result?id=",
searchLinkToPublication: "/search/publication?articleId=",
searchLinkToProject: "/search/project?projectId=",
searchLinkToDataProvider: "/search/dataprovider?datasourceId=",
searchLinkToDataset: "/search/dataset?datasetId=",
searchLinkToSoftwareLanding: "/search/software?softwareId=",
searchLinkToOrganization: "/search/organization?organizationId=",
searchLinkToOrp: "/search/other?orpId=",
searchLinkToResults: "/search/find/research-outcomes",
searchLinkToCommunities: "/search/find/communities",
searchLinkToPublications: '/search/find/research-outcomes?type="publications"',
searchLinkToDataProviders: "/search/find/dataproviders",
searchLinkToProjects: "/search/find/projects",
searchLinkToDatasets: '/search/find/research-outcomes?type="datasets"',
searchLinkToSoftware: '/search/find/research-outcomes?type="software"',
searchLinkToOrps: '/search/find/research-outcomes?type="other"',
searchLinkToOrganizations: "/search/find/organizations",
searchLinkToCompatibleDataProviders: "/search/content-providers",
searchLinkToEntityRegistriesDataProviders: "/search/entity-registries",
searchLinkToJournals: "/search/journals",
searchLinkToAdvancedResults: "/search/advanced/research-outcomes",
searchLinkToAdvancedPublications: "/search/advanced/publications",
searchLinkToAdvancedProjects: "/search/advanced/projects",
searchLinkToAdvancedDatasets: "/search/advanced/datasets",
searchLinkToAdvancedSoftware: "/search/advanced/software",
searchLinkToAdvancedOrps: "/search/advanced/other",
searchLinkToAdvancedDataProviders: "/search/advanced/dataproviders",
searchLinkToAdvancedOrganizations: "/search/advanced/organizations",
errorLink: '/error',
lastIndexInformationLink: "https://beta.openaire.eu/aggregation-and-content-provision-workflows",
showLastIndexInformationLink: true,
widgetLink: "https://beta.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
claimsInformationLink: "https://beta.openaire.eu/linking",
depositLearnHowPage: "/participate/deposit/learn-how",
depositSearchPage: "/participate/deposit/search",
shareInZenodoPage: "/participate/deposit/zenodo",
reCaptchaSiteKey: "6LezhVIUAAAAAOb4nHDd87sckLhMXFDcHuKyS76P",
admins: ["helpdesk@openaire.eu"],
lastIndexUpdate: "2019-08-07",
indexInfoAPI: "http://beta.services.openaire.eu/openaire/info/",
altMetricsAPIURL: "https://api.altmetric.com/v1/doi/"
domain: "https://beta.monitor.openaire.eu"
};
export let properties: EnvProperties = {
...common, ...commonBeta, ...props
}

View File

@ -1,122 +1,20 @@
import {EnvProperties} from "../app/openaireLibrary/utils/properties/env-properties";
import {common, commonProd} from "../app/openaireLibrary/utils/properties/environments/environment";
export let properties: EnvProperties = {
environment: "production",
let props: EnvProperties = {
dashboard: 'monitor',
isDashboard: true,
enablePiwikTrack: true,
useCache: false,
useLongCache: true,
showContent: true,
framesAPIURL: "https://www.openaire.eu/stats3/",
statisticsAPIURL: "https://services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://www.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://services.openaire.eu/stats-tool/",
useNewStatistisTool: true,
monitorStatsFrameUrl:"https://services.openaire.eu/stats-tool/",
monitorStatsFrameUrl: "https://services.openaire.eu/stats-tool/",
useOldStatisticsSchema: false,
claimsAPIURL: "https://services.openaire.eu/claims/rest/claimsService/",
searchAPIURLLAst: "https://services.openaire.eu/search/v2/api/",
searchResourcesAPIURL: "https://services.openaire.eu/search/v2/api/resources",
openCitationsAPIURL: "https://services.openaire.eu/opencitations/getCitations?id=",
csvAPIURL: "https://services.openaire.eu/search/v2/api/reports",
searchCrossrefAPIURL: "https://api.crossref.org/works",
searchDataciteAPIURL: "https://api.datacite.org/works",
searchOrcidURL: "https://pub.orcid.org/v2.1/",
orcidURL: "https://orcid.org/",
doiURL: "https://doi.org/",
pmcURL: "http://europepmc.org/articles/",
pmidURL: "https://www.ncbi.nlm.nih.gov/pubmed/",
handleURL: "http://hdl.handle.net/",
cordisURL: "http://cordis.europa.eu/projects/",
openDoarURL: "http://v2.sherpa.ac.uk/id/repository/",
r3DataURL: "http://service.re3data.org/repository/",
fairSharingURL: "https://fairsharing.org/",
eoscMarketplaceURL: "https://marketplace.eosc-portal.eu/services/",
sherpaURL: 'http://sherpa.ac.uk/romeo/issn/',
sherpaURLSuffix: '/',
zenodo: "https://zenodo.org/",
zenodoCommunities: "https://zenodo.org/api/communities/",
openAccess: "https://www.openaire.eu/support/faq#article-id-234",
openAccessRepo: "https://www.openaire.eu/support/faq#article-id-310",
fp7Guidlines: "https://www.openaire.eu/open-access-in-fp7-seventh-research-framework-programme",
h2020Guidlines: "https://www.openaire.eu/oa-publications/h2020/open-access-in-horizon-2020",
ercGuidlines: "http://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_2014.pdf",
helpdesk: 'https://www.openaire.eu/support/helpdesk',
helpdeskEmail: 'helpdesk@openaire.eu',
utilsService: "https://explore.openaire.eu/utils-service",
vocabulariesAPI: "https://services.openaire.eu/provision/mvc/vocabularies/",
piwikBaseUrl: "https://analytics.openaire.eu/piwik.php?idsite=",
piwikSiteId: "104",
loginUrl: "https://services.openaire.eu/login-service/openid_connect_login",
registryUrl: 'https://services.openaire.eu/uoa-user-management/api/registry/',
userInfoUrl: "https://services.openaire.eu/login-service/userInfo",
logoutUrl: "https://services.openaire.eu/login-service/openid_logout",
cookieDomain: ".openaire.eu",
feedbackmail: "feedback@openaire.eu",
cacheUrl: "https://explore.openaire.eu/cache/get?url=",
datasourcesAPI: "https://services.openaire.eu/openaire/ds/search/",
monitorServiceAPIURL: "https://services.openaire.eu/uoa-monitor-service",
adminToolsAPIURL: "https://services.openaire.eu/uoa-monitor-service/",
notificationsAPIURL: "https://services.openaire.eu/uoa-monitor-service/notification/",
adminToolsCommunity: "monitor",
useHelpTexts:true,
contextsAPI: "https://services.openaire.eu/openaire/context",
communityAPI: "https://services.openaire.eu/openaire/community/",
communitiesAPI: "https://services.openaire.eu/openaire/community/communities",
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
useHelpTexts: true,
baseLink: "/dashboard",
domain: "https://monitor.openaire.eu",
searchLinkToResult: "/search/result?id=",
searchLinkToPublication: "/search/publication?articleId=",
searchLinkToProject: "/search/project?projectId=",
searchLinkToDataProvider: "/search/dataprovider?datasourceId=",
searchLinkToDataset: "/search/dataset?datasetId=",
searchLinkToSoftwareLanding: "/search/software?softwareId=",
searchLinkToOrp: "/search/other?orpId=",
searchLinkToOrganization: "/search/organization?organizationId=",
searchLinkToResults: "/search/find/research-outcomes",
searchLinkToPublications: '/search/find/research-outcomes?type="publications"',
searchLinkToDataProviders: "/search/find/dataproviders",
searchLinkToProjects: "/search/find/projects",
searchLinkToDatasets: '/search/find/research-outcomes?type="datasets"',
searchLinkToSoftware: '/search/find/research-outcomes?type="software"',
searchLinkToOrps: '/search/find/research-outcomes?type="other"',
searchLinkToOrganizations: "/search/find/organizations",
searchLinkToCompatibleDataProviders: "/search/content-providers",
searchLinkToEntityRegistriesDataProviders: "/search/entity-registries",
searchLinkToJournals: "/search/journals",
searchLinkToAdvancedResults: "/search/advanced/research-outcomes",
searchLinkToAdvancedPublications: "/search/advanced/publications",
searchLinkToAdvancedProjects: "/search/advanced/projects",
searchLinkToAdvancedDatasets: "/search/advanced/datasets",
searchLinkToAdvancedSoftware: "/search/advanced/software",
searchLinkToAdvancedOrps: "/search/advanced/other",
searchLinkToAdvancedDataProviders: "/search/advanced/dataproviders",
searchLinkToAdvancedOrganizations: "/search/advanced/organizations",
errorLink: '/error',
lastIndexInformationLink: "https://www.openaire.eu/aggregation-and-content-provision-workflows",
showLastIndexInformationLink: true,
widgetLink: "https://www.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
claimsInformationLink: "https://www.openaire.eu/linking",
depositLearnHowPage: "/participate/deposit/learn-how",
depositSearchPage: "/participate/deposit/search",
shareInZenodoPage: "/participate/deposit/zenodo",
reCaptchaSiteKey: "6LezhVIUAAAAAOb4nHDd87sckLhMXFDcHuKyS76P",
admins: ["argirok@di.uoa.gr"],
lastIndexUpdate: "2019-07-24",
indexInfoAPI: "http://services.openaire.eu/openaire/info/",
altMetricsAPIURL: "https://api.altmetric.com/v1/doi/"
domain: "https://monitor.openaire.eu"
};
export let properties: EnvProperties = {
...common, ...commonProd, ...props
}

View File

@ -4,113 +4,24 @@
// The list of which env maps to which file can be found in `.angular-cli.json`.
import {EnvProperties} from "../app/openaireLibrary/utils/properties/env-properties";
import {common, commonDev} from "../app/openaireLibrary/utils/properties/environments/environment";
export let properties: EnvProperties = {
environment: "development",
let props: EnvProperties = {
dashboard: 'monitor',
adminToolsPortalType: "monitor",
isDashboard: true,
enablePiwikTrack: false,
useCache: false,
useLongCache: false,
showContent: true,
framesAPIURL: "https://beta.openaire.eu/stats3/",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://beta.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://beta.services.openaire.eu/stats-tool/",
useNewStatistisTool: true,
monitorStatsFrameUrl:"https://stats.madgik.di.uoa.gr/stats-api/",
useOldStatisticsSchema: false,
disableFrameLoad: true,
claimsAPIURL: "http://scoobydoo.di.uoa.gr:8080/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/",
searchAPIURLLAst: "https://beta.services.openaire.eu/search/v2/api/",
searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources",
openCitationsAPIURL: "https://services.openaire.eu/opencitations/getCitations?id=",
csvAPIURL: "http://rudie.di.uoa.gr:8080/dnet-functionality-services-2.0.0-SNAPSHOT/rest/v2/reports",
searchCrossrefAPIURL: "https://api.crossref.org/works",
searchDataciteAPIURL: "https://api.datacite.org/works",
searchOrcidURL: "https://pub.orcid.org/v2.1/",
orcidURL: "https://orcid.org/",
doiURL: "https://doi.org/",
pmcURL: "http://europepmc.org/articles/",
pmidURL: "https://www.ncbi.nlm.nih.gov/pubmed/",
handleURL: "http://hdl.handle.net/",
cordisURL: "http://cordis.europa.eu/projects/",
openDoarURL: "http://v2.sherpa.ac.uk/id/repository/",
r3DataURL: "http://service.re3data.org/repository/",
fairSharingURL: "https://fairsharing.org/",
eoscMarketplaceURL: "https://marketplace.eosc-portal.eu/services/",
sherpaURL: 'http://sherpa.ac.uk/romeo/issn/',
sherpaURLSuffix: '/',
zenodo: "https://zenodo.org/",
zenodoCommunities: "https://zenodo.org/api/communities/",
openAccess: "https://www.openaire.eu/support/faq#article-id-234",
openAccessRepo: "https://www.openaire.eu/support/faq#article-id-310",
fp7Guidlines: "https://www.openaire.eu/open-access-in-fp7-seventh-research-framework-programme",
h2020Guidlines: "https://www.openaire.eu/oa-publications/h2020/open-access-in-horizon-2020",
ercGuidlines: "http://erc.europa.eu/sites/default/files/document/file/ERC_Open_Access_Guidelines-revised_2014.pdf",
helpdesk: 'https://www.openaire.eu/support/helpdesk',
helpdeskEmail: 'helpdesk@openaire.eu',
utilsService: "http://mpagasas.di.uoa.gr:8000",
vocabulariesAPI: "https://dev-openaire.d4science.org/provision/mvc/vocabularies/",
piwikBaseUrl: "https://analytics.openaire.eu/piwik.php?idsite=",
piwikSiteId: "80",
registryUrl: 'http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/registry/',
loginUrl: "http://mpagasas.di.uoa.gr:19080/login-service/openid_connect_login",
userInfoUrl: "http://mpagasas.di.uoa.gr:19080/login-service/userInfo",
logoutUrl: "http://mpagasas.di.uoa.gr:19080/login-service/openid_logout",
cookieDomain: ".di.uoa.gr",
feedbackmail: "openaire.test@gmail.com",
cacheUrl: "http://scoobydoo.di.uoa.gr:3000/get?url=",
// monitorServiceAPIURL: "https://services.openaire.eu/uoa-monitor-service",
monitorServiceAPIURL: "http://duffy.di.uoa.gr:19380/uoa-monitor-service",
adminToolsAPIURL: "http://duffy.di.uoa.gr:19380/uoa-monitor-service/",
notificationsAPIURL: "http://duffy.di.uoa.gr:19380/uoa-monitor-service/notification/",
adminToolsCommunity: "monitor",
useHelpTexts: true,
datasourcesAPI: "https://beta.services.openaire.eu/openaire/ds/search/",
contextsAPI: "https://dev-openaire.d4science.org/openaire/context",
communityAPI: "https://dev-openaire.d4science.org/openaire/community/",
communitiesAPI: "https://dev-openaire.d4science.org/openaire/community/communities",
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
baseLink: "/dashboard",
domain: "http://mpagasas.di.uoa.gr:4600",
searchLinkToResult: "/search/result?id=",
searchLinkToPublication: "/search/publication?articleId=",
searchLinkToPublications: '/search/find/research-outcomes?type="publications"',
searchLinkToProject: "/search/project?projectId=",
searchLinkToDataProvider: "/search/dataprovider?datasourceId=",
searchLinkToDataset: "/search/dataset?datasetId=",
searchLinkToSoftwareLanding: "/search/software?softwareId=",
searchLinkToOrganization: "/search/organization?organizationId=",
searchLinkToOrp: "/search/other?orpId=",
searchLinkToResults: "/search/find/research-outcomes",
searchLinkToDataProviders: "/search/find/dataproviders",
searchLinkToProjects: "/search/find/projects",
searchLinkToOrganizations: "/search/find/organizations",
searchLinkToDatasets: '/search/find/research-outcomes?type="datasets"',
searchLinkToSoftware: '/search/find/research-outcomes?type="software"',
searchLinkToOrps: '/search/find/research-outcomes?type="other"',
searchLinkToCompatibleDataProviders: "/search/content-providers",
searchLinkToEntityRegistriesDataProviders: "/search/entity-registries",
searchLinkToJournals: "/search/journals",
searchLinkToAdvancedResults: "/search/advanced/research-outcomes",
searchLinkToAdvancedProjects: "/search/advanced/projects",
searchLinkToAdvancedDataProviders: "/search/advanced/dataproviders",
searchLinkToAdvancedOrganizations: "/search/advanced/organizations",
errorLink: '/error',
lastIndexInformationLink: "https://beta.openaire.eu/aggregation-and-content-provision-workflows",
showLastIndexInformationLink: true,
widgetLink: "https://beta.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
claimsInformationLink: "https://beta.openaire.eu/linking",
depositLearnHowPage: "/participate/deposit/learn-how",
depositSearchPage: "/participate/deposit/search",
shareInZenodoPage: "/participate/deposit/zenodo",
reCaptchaSiteKey: "6LcVtFIUAAAAAB2ac6xYivHxYXKoUvYRPi-6_rLu",
admins: ["kostis30fylloy@gmail.com", "argirok@di.uoa.gr"],
lastIndexUpdate: "2019-05-16",
indexInfoAPI: "http://beta.services.openaire.eu/openaire/info/",
altMetricsAPIURL: "https://api.altmetric.com/v1/doi/"
baseLink: "/",
domain: "http://mpagasas.di.uoa.gr:4600"
};
export let properties: EnvProperties = {
...common, ...commonDev, ...props
}

View File

@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<base href="/dashboard"/>
<base href="/"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<meta name="description" content="OpenAIRE Monitor, funder, funding, research, "/>
<meta property="og:description" content="OpenAIRE Monitor, funder, funding"/>

View File

@ -12,4 +12,4 @@ if (properties.environment !== "development") {
}
export { AppServerModule } from './app/app.server.module';
export { renderModule } from '@angular/platform-server';

View File

@ -5,6 +5,7 @@
@import "~src/assets/common-assets/less/general";
@import "~src/assets/common-assets/less/user";
@import "~src/assets/common-assets/less/dashboard";
@import "~src/assets/common-assets/less/indicators";
@import "~src/assets/common-assets/less/ckeditor";
@import "~src/assets/monitor-dashboard-custom";
@import "assets/print.css";

View File

@ -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);

View File

@ -2,7 +2,6 @@
"extends": "./tsconfig.app.json",
"compilerOptions": {
"outDir": "../out-tsc/app-server",
"target": "es2016",
"types": [
"node"
]

View File

@ -10,13 +10,14 @@
"moduleResolution": "node",
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2020",
"target": "ES2022",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
],
"useDefineForClassFields": false
}
}