Compare commits

...

270 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 bb6d744292 Update library before deploy 2023-04-27 15:40:52 +03:00
Konstantinos Triantafyllou 4eb3cb9e9f Update before deploy 2023-04-27 15:39:16 +03:00
Konstantinos Triantafyllou 0a673c84a5 Merge from develop 2023-04-26 12:28:17 +03:00
Konstantinos Triantafyllou fad8074285 Update uikit to 3.13.10 2023-04-26 12:20:27 +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 13dd4654d6 Update library 2023-04-24 12:26:06 +03:00
Konstantinos Triantafyllou f8af86c347 Update UIKit to 3.13.0 2023-04-24 12:25:20 +03:00
Konstantinos Triantafyllou 7ccfadf57b Update libraries before production deploy 2023-04-19 16:22:26 +03:00
Konstantinos Triantafyllou cacf062447 Merge pull request 'Update for production April Release' (#2) from develop into master
Reviewed-on: #2
2023-04-19 15:20:09 +02: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
Konstantinos Triantafyllou 0b793bba40 Fix bug with desciption overlay in monitor dashboard 2023-04-06 11:32:20 +03:00
Konstantinos Triantafyllou fbf9d91d03 Update libraries before beta deployment 2023-04-05 12:23:06 +03:00
Konstantinos Triantafyllou cc788e95dc Fix indicatator path undefiend in dashboard if subcategory is changed quickly. 2023-03-28 14:23:05 +03:00
Konstantinos Triantafyllou a9a849a309 Update library before deploy 2023-03-28 08:57:53 +03:00
Konstantinos Triantafyllou 685bb53425 Update libraries before beta deploy 2023-03-27 18:02:30 +03:00
Konstantinos Triantafyllou af751636b2 Hide manage pages from menus. Remove header from admin pages 2023-03-27 15:00:12 +03:00
Konstantinos Triantafyllou 409f263479 Add notification configuration in order to works in mobile 2023-03-24 17:15:41 +02:00
Konstantinos Triantafyllou b9381c41cf Manage Stakeholders: Remove uikit event handler and use cancelEmitter of modal. Update UIkit to 3.12.2 2023-03-23 12:24:11 +02:00
Konstantinos Triantafyllou 50255b1e7d Merge from production 2023-03-23 10:46:21 +02:00
Konstantinos Triantafyllou 9f9127ca91 General: Fix error while initilizing form when stakeholder is changed. 2023-03-23 10:45:16 +02:00
Konstantinos Triantafyllou 0440a5fbfa Update library before deployment 2023-03-23 09:19:36 +02:00
Konstantinos Triantafyllou 41e2eba62e Merge user-info fix from prodiuction. 2023-03-22 19:33:23 +02:00
Konstantinos Triantafyllou 3b8cf0e129 Update stakeholder if route is diff from user-info 2023-03-22 19:31:44 +02:00
Konstantinos Triantafyllou 6d18512491 Monitor page: Hide note in mobile. Change position of filters in mobile. 2023-03-22 17:56:50 +02:00
Konstantinos Triantafyllou abc1547c72 Update for production deploy 2023-03-21 14:16:01 +02:00
Konstantinos Triantafyllou 700c46f9b8 Merge pull request 'Update to latest changes' (#1) from develop into master
Reviewed-on: #1
2023-03-20 21:53:18 +01:00
Konstantinos Triantafyllou a68b64c35a Merge branch 'develop' of code-repo.d4science.org:MaDgIK/monitor-dashboard into develop 2023-03-20 19:32:20 +02:00
Konstantinos Triantafyllou 7e06e34034 Fix set open for sidebar in app.component 2023-03-20 19:32:10 +02:00
Alex Martzios 4da9f10d20 add color coding for type of stakeholder - manage stakeholders page, update submodules 2023-03-17 16:34:08 +02:00
Konstantinos Triantafyllou b2bda20498 Change manage profiles to the new Back Item for sidebar. Change back in topics in order to be the same with the back of sidebar 2023-03-01 15:22:49 +02:00
Konstantinos Triantafyllou f76bf6091d Add mobile view for monitor page and add change tabs to slider-tabs 2023-02-15 12:53:47 +02:00
Konstantinos Triantafyllou 74934c1a8b Fix a bug while getting numbers of previous active subcategory. Fix sidebar in topics 2023-01-27 15:58:21 +02:00
Konstantinos Triantafyllou bf97a1ff2a Make grid small for indicators. 2023-01-26 16:50:01 +02:00
Konstantinos Triantafyllou 55efe4b09a Add toggle and hover behaviour in sidebar 2023-01-25 08:01:33 +02:00
Konstantinos Triantafyllou 6709deb903 Fix role-verification display if a dashboard is private or restricted. 2023-01-20 17:32:27 +02:00
Konstantinos Triantafyllou 1719469e56 Update libraries before beta and production deployment 2023-01-13 11:34:22 +02:00
Konstantinos Triantafyllou b3403a65cf Some fixes regarding Preview mode. Change round of numbers to over 1M and to one decimal. 2023-01-11 16:09:26 +02:00
Konstantinos Triantafyllou 7568509b95 Fix margins in private content view 2023-01-04 11:55:20 +02:00
Konstantinos Triantafyllou b308e07e1a Change private overlay image and content. Hide categories in manage indicators on server 2022-12-23 17:37:42 +02:00
Konstantinos Triantafyllou 2f70686638 Fix flex align in manage indicators for preview button and page heading 2022-12-22 11:41:04 +02:00
Konstantinos Triantafyllou 7907d3e04a Remove animation from preview button 2022-12-21 18:03:19 +02:00
Konstantinos Triantafyllou cdf9872efa Move preview in the above row of subcategories and show it next to them in sticky 2022-12-21 14:38:00 +02:00
Konstantinos Triantafyllou 8077d58cd7 Round numbers in monitor and admin indicators 2022-12-21 13:40:47 +02:00
Konstantinos Triantafyllou 670dfe6e0a Change preview logic and fix permissions in all pages. Add preview bar when user is on a preview mode 2022-12-20 17:40:46 +02:00
Konstantinos Triantafyllou 8ec038b5b8 Revert powered by in monitor page 2022-12-15 18:08:31 +02:00
Konstantinos Triantafyllou 3ea3f7a8dd Move wrong divider in subcategory menu 2022-12-15 11:30:45 +02:00
Konstantinos Triantafyllou 3613e8dd88 Revert import/export indicators in subcategories, deleted by mistake. 2022-12-15 11:28:11 +02:00
Konstantinos Triantafyllou 61e7c6249b Make subcategories uppercase and add powered by monitor in footer 2022-12-12 19:02:37 +02:00
Alex Martzios 0ed68b21fa remove "Admin Dashboard -" title and logo from monitor admin pages, update submodules 2022-12-12 16:59:59 +02:00
Konstantinos Triantafyllou cf7094bcf0 Change logo of monitor with stakeholder's both in dashboard and admin. Remove logo and Admin dashboard title from Mangege Profile and Manage profiles 2022-12-12 16:18:55 +02:00
Konstantinos Triantafyllou 82b9a57b22 Merge branch 'master' of code-repo.d4science.org:MaDgIK/monitor-dashboard 2022-12-09 18:03:34 +02:00
Konstantinos Triantafyllou e0ede6efa8 1. Add isCurator in create a category. 2. Hide delete section if it not permitted and make manage roles visible to curators and superAdmins 2022-12-09 18:03:19 +02:00
Konstantina Galouni dbc836a969 [Monitor Dashboard | angular-14]: environments/: Set property dashboard: 'monitor'. 2022-11-29 18:13:55 +02:00
Konstantinos Triantafyllou b1397944a1 Fix a bug with category visibility in manage indicators 2022-11-28 17:31:01 +02:00
Konstantinos Triantafyllou 792108684e Add missing about menu subitems 2022-11-09 12:36:14 +02:00
Konstantinos Triantafyllou 9cc66b6191 Update before beta deploy 2022-11-09 11:56:48 +02:00
Konstantinos Triantafyllou bfd19dfaf3 Change description in numbers card in monitor dashboard. Fix infinite loop from last commit in error page. 2022-11-08 16:37:44 +02:00
Konstantinos Triantafyllou 7e4e6e6d46 Change position of note and fix padding in number indicators 2022-11-08 15:35:48 +02:00
Konstantinos Triantafyllou 8e978b0c9f Fix a bug in topics while delete the active entity. Fix a bug with infinity loading when a topic or category is not found. 2022-11-08 15:10:20 +02:00
Konstantinos Triantafyllou 53446ed998 Enlarge modal in edit topic/category/subcategory. Change number indicators view 2022-11-08 09:54:18 +02:00
Konstantinos Triantafyllou f7db2d03b2 Merge indicators and indicators/:topic path in one route configuration. Fix transitions in admin dashboard 2022-11-07 17:01:30 +02:00
Konstantinos Triantafyllou b970b9c302 Add new sidebar in topics component (need to investigate about transition). Add hasInternalSidebar for topics component. Move categories under topics in monitor sidebar 2022-11-04 16:36:51 +02:00
argirok fea494fd0e Merge branch 'master' of https://code-repo.d4science.org/MaDgIK/monitor-dashboard 2022-10-25 18:42:37 +03:00
Konstantinos Triantafyllou a8ab4c2e58 Fix notification message while change the status of an element and its content 2022-10-25 18:42:24 +03:00
argirok 2ad18e5899 fix related to #8135: count properly the filters applied in the parameters 2022-10-25 18:41:51 +03:00
Konstantinos Triantafyllou 191855d64d Relocate preview button from sidebar to header actions. 2022-10-24 11:31:16 +03:00
Konstantinos Triantafyllou b07958c9e3 Rename sourceMap to source-map in package.json 2022-10-23 02:58:16 +03:00
Konstantinos Triantafyllou 4060033e34 Merge from master 2022-10-23 02:15:13 +03:00
argirok ef45a417b0 make the rule to apply year filter more generic, but exclude "indi_pub_downloads_year.year" according to #8135 2022-10-17 14:22:07 +03:00
argirok 1e2a7cff85 Merge branch 'master' of code-repo.d4science.org:MaDgIK/monitor-dashboard 2022-10-17 12:44:57 +03:00
Konstantinos Triantafyllou 44427dba5f Fix change status of stakeholder and indicator. Add new APIs in development environment. 2022-10-14 14:59:36 +03:00
argirok 7347a06eea Indicator utils fixes - related to #8135
- count applied filters when the filter is applied to a field tha has a parameter filter
- apply filters in all select fields not only in the 1st
2022-10-11 10:24:34 +03:00
argirok 4d7cadbaa7 fix #8107: chart is not properly displayed because filter on field "No Of Funders" was replaced with funder name 2022-10-03 16:00:57 +03:00
argirok 1a13bd942c fix #8107: chart is not properly displayed because filter on field "No Of Funders" was replaced with funder name 2022-10-03 15:29:39 +03:00
Konstantinos Triantafyllou 1329d43ca6 Disable inline critical css in angular.json 2022-10-03 13:36:12 +03:00
Konstantinos Triantafyllou 371720080e Update submodules 2022-10-03 12:27:53 +03:00
Konstantinos Triantafyllou ac79cdf2c8 Disable inline critical css in server.ts 2022-10-03 12:27:10 +03:00
Konstantinos Triantafyllou f407ecbb73 Update library before beta deployment 2022-09-28 12:19:44 +03:00
Konstantinos Triantafyllou e00fbd3ce5 Add types/ckeditor in dev dependencies 2022-09-26 18:05:13 +03:00
Konstantinos Triantafyllou 55b892afc8 Update recaptch to version 10.0.0 and ckeditor to 1.3.7. 2022-09-26 17:44:05 +03:00
Konstantinos Triantafyllou aad408b5fa Add .angular folder in after-build-clean 2022-09-23 15:18:25 +03:00
Konstantinos Triantafyllou c7320a9e9e Add .angular folder in gitignore 2022-09-23 15:08:26 +03:00
Konstantinos Triantafyllou d0a378158f Update submodules and fix search route configuration 2022-09-23 14:12:05 +03:00
Konstantinos Triantafyllou 451331ba57 Update express engine to version 14 2022-09-23 13:26:53 +03:00
Konstantinos Triantafyllou 3cdbf16fa2 Update material to version 14 2022-09-23 13:26:19 +03:00
Konstantinos Triantafyllou 612fa0ef2f Update angular core and cli to version 14 2022-09-23 13:25:18 +03:00
Konstantinos Triantafyllou 4ea92912d2 Remove renderModuleFactory (deprecated) 2022-09-23 13:18:31 +03:00
Konstantinos Triantafyllou 62382fb07d Update express-engine to version 13 2022-09-23 12:50:35 +03:00
Konstantinos Triantafyllou e8f4729aba Update material to version 13 2022-09-23 12:49:43 +03:00
Konstantinos Triantafyllou c4565f4a00 Update angular core and cli to version 13 2022-09-23 12:47:58 +03:00
Konstantinos Triantafyllou 7b014fe3d6 Update angular express engine to version 12 2022-09-23 12:42:13 +03:00
Konstantinos Triantafyllou eb08ace6e6 Update angular material to version 12 2022-09-23 12:41:29 +03:00
Konstantinos Triantafyllou cd34cac238 Update angular core and cli to version 12 2022-09-23 12:40:28 +03:00
Konstantinos Triantafyllou 9d71dc354c Update modules before update 2022-09-23 12:38:39 +03:00
Konstantinos Triantafyllou 6478a81695 Update modules before angular upgrade branch 2022-09-23 11:58:33 +03:00
Konstantinos Triantafyllou 0dc9fea22a Merge remote-tracking branch 'origin/privacy-settings' into new-theme 2022-09-21 14:43:35 +03:00
Konstantinos Triantafyllou c79ccdc25e Update modules before deployment. Remove environement condition for resources 2022-09-21 12:03:18 +03:00
Konstantinos Triantafyllou 7fc44422cf Merge remote-tracking branch 'origin/new-theme' into privacy-settings 2022-09-21 11:45:11 +03:00
Alex Martzios 301fee1246 update submodule 2022-09-21 11:38:24 +03:00
Konstantina Galouni b88667a3fd [Monitor Dashboard | new-theme]: app.component.ts: Removed deprecated RootMenuItem and used MenuItem instead. 2022-09-20 23:59:26 +03:00
Konstantinos Triantafyllou 014c0b0825 Merge remote-tracking branch 'origin/new-theme' into privacy-settings 2022-09-20 11:03:18 +03:00
Alex Martzios dde969d066 change description to note in indicators preview 2022-09-20 11:02:05 +03:00
Alex Martzios 5f3897da5a change description to note in indicators preview 2022-09-20 10:59:13 +03:00
Konstantinos Triantafyllou 5ac6847e65 Merge remote-tracking branch 'origin/new-theme' into privacy-settings 2022-09-19 17:15:27 +03:00
Alex Martzios 892253b2a1 update submodule 2022-09-19 17:08:21 +03:00
Alex Martzios 21ce37b3a5 update submodule 2022-09-19 16:48:00 +03:00
argirok c0f76eb601 fix import indicators with no numbers - create separate method to migrate from old json format. 2022-09-19 16:38:36 +03:00
Konstantinos Triantafyllou 22b22f4afa Merge branch 'new-theme' of code-repo.d4science.org:MaDgIK/monitor-dashboard into new-theme 2022-09-19 14:43:33 +03:00
Konstantinos Triantafyllou 9b494fcf5a Quick fix for import indicators 2022-09-19 14:42:59 +03:00
Alex Martzios 7daa57ada3 update submodules 2022-09-15 11:56:15 +03:00
Alex Martzios 3bfd648ee8 text changes for topics' visibility modal content 2022-09-15 11:50:24 +03:00
Alex Martzios 0a3860bb4c improve status of topics, categories, subcategories and indicators with new modal message and clickable options 2022-09-14 16:32:52 +03:00
Konstantinos Triantafyllou 4ed0890bb9 Fix a bug with active subcategory in admin 2022-09-13 13:30:16 +03:00
argirok 35e4563144 fix export indicators not in the current active subcategory 2022-09-09 13:00:39 +03:00
argirok 06959c7526 Merge branch 'new-theme' of code-repo.d4science.org:MaDgIK/monitor-dashboard into new-theme 2022-09-08 17:49:45 +03:00
argirok a3b2d58dc9 export: add section information
import: sends a list of sections to save instead of a list of indicators
2022-09-08 17:45:59 +03:00
Konstantinos Triantafyllou a9a0452632 Fix manage stakeholders loading stuck in case of session expired. 2022-09-08 16:51:10 +03:00
argirok 62dff971f3 manage indicators page add checks 2022-09-08 16:40:00 +03:00
Konstantinos Triantafyllou c1bc7b6a5a Fix a transition initilization after deleting a subcategory 2022-09-08 15:10:01 +03:00
Alex Martzios 3d6cbf8b3e add changes for fullscreen chart view on monitor component as well 2022-09-07 15:20:43 +03:00
Alex Martzios e510da08de remove 'uk-blend-multiply' from charts and add it conditionally for fullscreen view to work 2022-09-07 14:52:48 +03:00
Konstantinos Triantafyllou dc32e4c99d Update library before beta deploy 2022-08-31 13:17:01 +03:00
Konstantinos Triantafyllou 6245e80e53 Update library before beta deploy 2022-08-31 12:56:08 +03:00
Konstantinos Triantafyllou 01fbf9c3f6 Update routing of indicators pages 2022-08-29 16:58:03 +03:00
Konstantina Galouni c65174dbcd [Monitor Dashboard | new-theme]: Updated develop page and added example | Made graph and feedback line sticky in indicators' page.
1. develop.component.ts: Added example bullet for research products & Updated view of bullets (removed quotes - type bold).
2. page-content.component.ts:
   a. Added <div id="page_content_sticky_footer" #sticky_footer> and <div id="page_content_footer" #footer>.
   b. Added methods "ngAfterContentChecked()", "observeStickyFooter()", "calcStickyFooterOffset()" to calculate offset of sticky footer.
3. monitor.component.html: Added graph & feedback line as sticky_footer in >= medium screens and as footer in small screens.
2022-08-29 14:57:05 +03:00
Konstantinos Triantafyllou c65047f61d Add entities in app component in order to handle notification groups properly. 2022-08-05 15:00:21 +03:00
Alex Martzios 8ca270d48a add routing for indicator themes page and update submodules 2022-08-05 11:34:56 +03:00
Konstantinos Triantafyllou 3e1100e0ad Change back icon for manage profiles 2022-08-04 17:59:31 +03:00
Alex Martzios 170a93d108 add loading for modals: edit/create/delete topics and indicators 2022-08-04 17:45:43 +03:00
Konstantinos Triantafyllou f9dc782008 Change header info style. Fix menu in admin routes. Add replaceHeader for dashboard and stakeholder admin. 2022-08-04 15:33:49 +03:00
Alex Martzios bcbbefc277 add loading when editing/creating stakeholder profiles 2022-08-04 12:28:55 +03:00
Konstantinos Triantafyllou 48467c7172 Remove dx from doi properties and delete removed table properties 2022-08-03 21:05:07 +03:00
Konstantinos Triantafyllou adcc611fd7 Remove margin from plus at create category/subcategory 2022-08-02 23:42:38 +03:00
Konstantinos Triantafyllou ec9046569e Add some missing monitor styles. Fix monitor menu items base on home pages 2022-08-02 23:34:30 +03:00
Konstantinos Triantafyllou 71f6c494fb Update library before beta deploy 2022-08-02 23:23:48 +03:00
Konstantinos Triantafyllou 17b7d4296a Add resources menu item if environment is not production. Add placeholder in manage stakeholders 2022-08-02 23:15:38 +03:00
Konstantinos Triantafyllou 6a952b2615 Fix period filter and add filters counter 2022-08-02 10:42:23 +03:00
Konstantinos Triantafyllou bd02944e07 Disable frames load for dev, committed by mistake. 2022-07-29 14:48:43 +03:00
Konstantinos Triantafyllou 9d110a6fbf Merge branch 'new-theme' of code-repo.d4science.org:MaDgIK/monitor-dashboard into new-theme 2022-07-29 14:47:42 +03:00
Konstantinos Triantafyllou ea613919c3 Fix a bug when you are saving a topic, etc., this triggers transition. Add dev condition for resources menu item 2022-07-29 14:47:32 +03:00
Alex Martzios b49937d756 show number indicator description similar to charts 2022-07-28 16:05:26 +03:00
Konstantinos Triantafyllou 26cb6eace9 Add indicators page in stakeholder dashboard. Add resources in menu and add methodology and indicators as sub items 2022-07-27 12:36:18 +03:00
Alex Martzios f7686f2ba4 add subcategory description on top of the indicators 2022-07-26 15:24:53 +03:00
Alex Martzios 6a8637d994 update submodules 2022-07-25 15:39:43 +03:00
Konstantinos Triantafyllou e08f808564 Update library before beta deployment 2022-07-25 12:02:18 +03:00
Konstantinos Triantafyllou 5322118b42 Delete dashboard-theme 2022-07-25 11:19:53 +03:00
Konstantinos Triantafyllou f567e9d215 Merge branch 'new-theme' of code-repo.d4science.org:MaDgIK/monitor-dashboard into new-theme 2022-07-25 11:18:58 +03:00
Konstantinos Triantafyllou 555c717e21 Monitor page: Fix margins 2022-07-25 11:18:46 +03:00
Alex Martzios 5d8a3319ea rename "Search" menu item to "Browse data" + update submodules 2022-07-19 14:53:37 +03:00
Konstantinos Triantafyllou d5eff684cd Import specific less files from library instead of _import 2022-07-18 12:20:27 +03:00
Konstantinos Triantafyllou ac0d97404a Rename all component css to less. Import less from common-assets and delete deprecated.css. Remove dashboard-theme submodule 2022-07-17 16:24:47 +03:00
Konstantinos Triantafyllou 4ece9a5b60 Fix a bug with guard losing redirection. Add reorder in topics, categories, subcategories for Curators 2022-07-14 17:44:53 +03:00
Konstantinos Triantafyllou 3ffed87ad4 Topics: Add reorder functionality. Change sticky header to sticky actions in general, monitor and manage stakeholders 2022-07-14 14:38:20 +03:00
80 changed files with 1009 additions and 7772 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.angular/
node_modules/
dist/
.idea/

3
.gitmodules vendored
View File

@ -4,9 +4,6 @@
[submodule "src/assets/common-assets"]
path = src/assets/common-assets
url = gitea@code-repo.d4science.org:MaDgIK/openaire-assets.git
[submodule "src/assets/dashboard-theme"]
path = src/assets/dashboard-theme
url = gitea@code-repo.d4science.org:MaDgIK/dashboard-theme.git
[submodule "src/assets/openaire-theme"]
path = src/assets/openaire-theme
url = gitea@code-repo.d4science.org:MaDgIK/openaire-theme.git

View File

@ -22,7 +22,6 @@
"skipTests": true
},
"@schematics/angular:module": {
"skipTests": true
},
"@schematics/angular:pipe": {
"skipTests": true
@ -35,7 +34,6 @@
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"aot": true,
"outputPath": "dist/monitor-dashboard/browser",
"index": "src/index.html",
"main": "src/main.ts",
@ -47,22 +45,34 @@
],
"styles": [
"src/styles.less",
"src/deprecated.css",
"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"
]
],
"vendorChunk": true,
"extractLicenses": false,
"buildOptimizer": false,
"sourceMap": true,
"optimization": false,
"namedChunks": true
},
"configurations": {
"development": {
"optimization": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
@ -85,11 +95,17 @@
"with": "src/environments/environment.beta.ts"
}
],
"optimization": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
@ -124,11 +140,17 @@
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"optimization": {
"scripts": true,
"styles": {
"minify": true,
"inlineCritical": false
},
"fonts": true
},
"outputHashing": "all",
"sourceMap": false,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
@ -144,7 +166,8 @@
}
]
}
}
},
"defaultConfiguration": ""
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
@ -179,30 +202,23 @@
]
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": [
"src/tsconfig.app.json",
"src/tsconfig.spec.json"
],
"exclude": [
"**/node_modules/**"
]
}
},
"server": {
"builder": "@angular-devkit/build-angular:server",
"options": {
"outputPath": "dist/monitor-dashboard/server",
"main": "server.ts",
"tsConfig": "src/tsconfig.server.json"
"tsConfig": "src/tsconfig.server.json",
"sourceMap": true,
"optimization": false,
"buildOptimizer": false
},
"configurations": {
"development": {
"outputHashing": "media",
"sourceMap": false,
"optimization": true
"optimization": true,
"vendorChunk": true,
"buildOptimizer": true
},
"beta": {
"outputHashing": "media",
@ -213,7 +229,8 @@
}
],
"sourceMap": false,
"optimization": true
"optimization": true,
"buildOptimizer": true
},
"production": {
"outputHashing": "media",
@ -224,9 +241,11 @@
}
],
"sourceMap": false,
"optimization": true
"optimization": true,
"buildOptimizer": true
}
}
},
"defaultConfiguration": ""
},
"serve-ssr": {
"builder": "@nguniversal/builders:ssr-dev-server",
@ -272,18 +291,8 @@
"devServerTarget": "monitor-dashboard:serve:production"
}
}
},
"lint": {
"builder": "@angular-devkit/build-angular:tslint",
"options": {
"tsConfig": "e2e/tsconfig.e2e.json",
"exclude": [
"**/node_modules/**"
]
}
}
}
}
},
"defaultProject": "monitor-dashboard"
}
}

View File

@ -1,62 +1,64 @@
{
"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 --prod --base-href /dashboard/ --sourceMap ",
"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",
"build:ssr-prod": "npm run build-prod && ng run monitor-dashboard:server:production",
"prerender": "ng run monitor-dashboard:prerender",
"after-build-clean": "rm -rf dist/monitor-dashboard/browser/assets/common-assets/.git src/app/openaireLibrary/.git node_modules src/assets/common-assets/.git .git"
"after-build-clean": "rm -rf dist/monitor-dashboard/browser/assets/common-assets/.git src/app/openaireLibrary/.git node_modules .angular src/assets/common-assets/.git .git"
},
"private": true,
"dependencies": {
"@angular/animations": "~11.2.14",
"@angular/cdk": "^11.2.13",
"@angular/common": "~11.2.14",
"@angular/compiler": "~11.2.14",
"@angular/core": "~11.2.14",
"@angular/forms": "~11.2.14",
"@angular/localize": "^11.2.14",
"@angular/material": "^11.2.13",
"@angular/platform-browser": "~11.2.14",
"@angular/platform-browser-dynamic": "~11.2.14",
"@angular/platform-server": "~11.2.14",
"@angular/router": "~11.2.14",
"@nguniversal/express-engine": "^11.2.1",
"@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": "^7.0.1",
"ng2-ckeditor": "1.3.1",
"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.12.0",
"zone.js": "~0.10.2"
"uikit": "3.16.24",
"zone.js": "~0.13.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.1102.14",
"@angular/cli": "~11.2.14",
"@angular/compiler-cli": "~11.2.14",
"@angular/language-service": "~11.2.14",
"@nguniversal/builders": "^11.2.1",
"@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/node": "^16.18.50",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.8.0",
"jasmine-spec-reporter": "~5.0.0",
@ -67,6 +69,6 @@
"karma-jasmine-html-reporter": "^1.6.0",
"protractor": "~7.0.0",
"ts-node": "~7.0.0",
"typescript": "~4.0.7"
"typescript": "~4.9.5"
}
}

101
server.ts
View File

@ -1,14 +1,23 @@
import 'zone.js/dist/zone-node';
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,22 +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, {
@ -50,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

@ -1,12 +1,12 @@
import {NgModule} from "@angular/core";
import {RouterModule} from "@angular/router";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
@NgModule({
imports: [RouterModule.forChild([
{
path: '',
loadChildren: () => import('../general/general.module').then(m => m.GeneralModule),
data: {hasAdminMenu: true},
loadChildren: () => import('../openaireLibrary/monitor-admin/general/general.module').then(m => m.GeneralModule),
pathMatch: 'full'
},
{
@ -17,26 +17,18 @@ import {RouterModule} from "@angular/router";
{
path: 'users/:user_type',
loadChildren: () => import('../users/users.module').then(m => m.UsersModule),
data: {hasAdminMenu: true},
pathMatch: 'full'
},
{
path: 'indicators',
loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule),
pathMatch: 'full'
},
{
path: 'indicators/:topic',
loadChildren: () => import('../topic/topic.module').then(m => m.TopicModule),
matcher: HelperFunctions.routingMatcher(['indicators', 'indicators/:topic']),
loadChildren: () => import('../openaireLibrary/monitor-admin/topic/topic.module').then(m => m.TopicModule),
data: {hasInternalSidebar: true},
pathMatch: 'full'
},
{
path: 'admin-tools',
loadChildren: () => import('../admin-tools/admin-tools-routing.module').then(m => m.AdminToolsRoutingModule),
data: {
hasAdminMenu: true,
param: 'stakeholder'
}
data: {param: 'stakeholder', parentClass: 'monitor'}
}
])]
})

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 = [
{
@ -11,6 +11,11 @@ const routes: Routes = [
loadChildren: () => import('./reload/libReload.module').then(m => m.LibReloadModule),
data: {hasSidebar: false}
},
{
path: 'user-info',
loadChildren: () => import('./login/libUser.module').then(m => m.LibUserModule),
data: {hasSidebar: false}
},
{
path: 'error',
component: OpenaireErrorPageComponent,
@ -18,36 +23,39 @@ 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}
data: {hasAdminMenu: true, hasSidebar: false}
},
{
path: 'admin/user-info',
loadChildren: () => import('./login/libUser.module').then(m => m.LibUserModule),
data: {hasAdminMenu: true}
data: {hasAdminMenu: true, hasSidebar: false}
},
{
path: 'admin/admin-tools',
loadChildren: () => import('./admin-tools/portal-admin-tools-routing.module').then(m => m.PortalAdminToolsRoutingModule),
canActivateChild: [AdminLoginGuard],
data: {hasAdminMenu: true}
data: {hasAdminMenu: true, hasSidebar: false}
},
{
path: 'admin/monitor/admin-tools',
loadChildren: () => import('./admin-tools/admin-tools-routing.module').then(m => m.AdminToolsRoutingModule),
canActivateChild: [AdminLoginGuard],
data: {hasAdminMenu: true, portal: 'monitor'}
data: {hasAdminMenu: true, hasSidebar: false, portal: 'monitor', monitorCurator: true, parentClass: 'monitor'}
},
{
path: 'admin/:stakeholder',
loadChildren: () => import('./admin-stakeholder/admin-stakeholder-routing.module').then(m => m.AdminStakeholderRoutingModule),
canActivateChild: [AdminDashboardGuard],
data: {
activeMenuItem: "manage"
}
data: {hasAdminMenu: true, hasSidebar: false, activeMenuItem: "manage"}
},
{
path: 'theme',
loadChildren: () => import('./openaireLibrary/utils/theme/theme.module').then(m => m.ThemeModule),
canActivateChild: [AdminLoginGuard],
data: {hasSidebar: false, hasHeader: false, monitorCurator: true, monitorManager: true}
},
{path: 'theme', loadChildren: () => import('./openaireLibrary/utils/theme/theme.module').then(m => m.ThemeModule)},
{
path: '',
loadChildren: () => import('./monitor/monitor.module').then(m => m.MonitorModule),

View File

@ -1,23 +1,70 @@
<div *ngIf="loading">
<loading [full]="true"></loading>
</div>
<div *ngIf="!loading" [class.stakeholderPage]="isFrontPage">
<div id="container" class="sidebar_main_swipe" [class.sidebar_main_active]="open && (hasSidebar || hasAdminMenu)"
[class.sidebar_mini]="!open && hasSidebar && (!hasAdminMenu || hasAdminMenu)">
<div id="modal-container"></div>
<navbar *ngIf="hasHeader" portal="monitor_dashboard" [header]="menuHeader" [dark]="isFrontPage"
[userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user" [offCanvasFlip]="true"></navbar>
<div *ngIf="!loading" [class.monitor]="isFrontPage">
<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" queryParamsHandling="merge" [items]="sideBarItems" [activeItem]="activeTopic?activeTopic.alias:null"></dashboard-sidebar>
<dashboard-sidebar *ngIf="hasAdminMenu" [items]="adminMenuItems" [specialMenuItem]="specialSideBarMenuItem"></dashboard-sidebar>
<main>
<router-outlet></router-outlet>
</main>
<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>
<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>
</div>
<bottom id="bottom" *ngIf="isFrontPage" [darkBackground]="false"
[centered]="true" [properties]="properties" [showMenuItems]="true"></bottom>
<role-verification *ngIf="stakeholder" [id]="stakeholder.alias" [name]="stakeholder.name" [type]="stakeholder.type"></role-verification>
<notification-sidebar *ngIf="user && notificationGroupsInitialized"
[user]="user" [availableGroups]="notificationGroups" service="monitor"></notification-sidebar>
</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">
<img src="assets/common-assets/logo-services/monitor/inverted.svg" style="height: 80px;">
<h1 class="uk-h4 uk-margin-large-top">Private Content</h1>
<div class="uk-text-large">
The contents of this dashboard are only visible to invited members.
</div>
<div class="uk-margin-large-top uk-margin-large-bottom">
<icon name="incognito" ratio="7"></icon>
</div>
<div class="uk-margin-medium-bottom">
<div *ngIf="!user">
If you are a member of this dashboard, please sign in.
</div>
<div>
If you want to be a member of this dashboard - Contact us.
</div>
</div>
<div class="uk-flex uk-flex-center uk-flex-middle">
<a *ngIf="!user" class="uk-button uk-button-primary uk-margin-right" (click)="login()">Sign in</a>
<a class="uk-button uk-button-secondary" [href]="monitorLink + '/contact-us'">Contact us</a>
</div>
</div>
</div>
<role-verification *ngIf="stakeholder" [id]="stakeholder.alias" [name]="stakeholder.name" [type]="stakeholder.type" [userInfoLink]="monitorLink + '/user-info'"></role-verification>
</div>

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,42 +1,53 @@
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';
import {UserManagementService} from "./openaireLibrary/services/user-management.service";
import {StakeholderService} from "./openaireLibrary/monitor/services/stakeholder.service";
import {BehaviorSubject, Subscriber} from "rxjs";
import {BehaviorSubject, Subscriber, Subscription} from "rxjs";
import {LayoutService} from "./openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {MenuItem, RootMenuItem} from "./openaireLibrary/sharedComponents/menu";
import {Stakeholder, Topic, Visibility} from "./openaireLibrary/monitor/entities/stakeholder";
import {MenuItem} from "./openaireLibrary/sharedComponents/menu";
import {
Category,
Stakeholder,
StakeholderEntities,
Topic,
Visibility
} from "./openaireLibrary/monitor/entities/stakeholder";
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";
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;
params: BehaviorSubject<Params> = new BehaviorSubject<Params>(null);
data: BehaviorSubject<Data> = new BehaviorSubject<Data>(null);
updateStakeholder: boolean = true;
hasSidebar: boolean = false;
hasHeader: boolean = false;
hasAdminMenu: boolean = false;
hasInternalSidebar: boolean = false;
isFrontPage: boolean = false;
isViewPublic: boolean = false;
sideBarItems: MenuItem[] = [];
specialSideBarMenuItem: MenuItem = null;
menuItems: RootMenuItem[] = [];
notificationGroups: Option[] = [];
isMobile: boolean = false;
view: Visibility;
menuItems: MenuItem[] = [];
notificationGroupsInitialized: boolean = false;
notificationConfiguration: NotificationConfiguration = new NotificationConfiguration();
stakeholderUtils: StakeholderUtils = new StakeholderUtils();
menuHeader: Header = {
route: "/",
@ -44,59 +55,39 @@ export class AppComponent implements OnInit, OnDestroy {
title: "Default menu header",
logoUrl: null,
logoSmallUrl: null,
position: 'center',
position: 'left',
badge: true,
stickyAnimation: true,
menuPosition: "center"
};
userMenuItems: MenuItem[] = [];
adminMenuItems: MenuItem[] = [];
stakeholder: Stakeholder = null;
activeTopic: Topic = null;
activeCategory: Category = null;
loading: boolean = true;
paramsResolved: boolean = false;
innerWidth;
private subscriptions: any[] = [];
constructor(private route: ActivatedRoute,
private router: Router,
projectUpdate: 'danger' | 'warning';
paramsSubscription: Subscription;
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) {
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);
}
}));
private configurationService: ConfigurationService,
private resourcesService: ResourcesService) {
super();
this.initRouterParams(_route);
}
@HostListener('window:resize', ['$event'])
onResize(event) {
if (this.layoutService.isSmallScreen && event.target.innerWidth > 640) {
this.layoutService.setSmallScreen(false);
} else if (!this.layoutService.isSmallScreen && event.target.innerWidth <= 640) {
this.layoutService.setSmallScreen(true);
this.layoutService.setOpen(false);
}
}
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();
@ -109,89 +100,116 @@ export class AppComponent implements OnInit, OnDestroy {
this.isFrontPage = isFrontPage;
this.cdr.detectChanges();
}));
this.route.queryParams.subscribe(params => {
this.isViewPublic = (params['view'] == 'public');
});
this.layoutService.setSmallScreen((this.innerWidth && this.innerWidth <= 640));
this.layoutService.setOpen(!(this.innerWidth && this.innerWidth <= 640));
this.subscriptions.push(this.params.subscribe(params => {
if (this.paramsResolved) {
this.loading = true;
if (params && params['stakeholder']) {
if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder']) {
this.subscriptions.push(this.stakeholderService.getStakeholder(params['stakeholder']).subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = stakeholder;
LinksResolver.setProperties(this.stakeholder.alias);
this.setProperties(this.stakeholder.alias, this.stakeholder.type);
if (params && params['topic'] && !this.activeTopic) {
this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && this.isPublicOrIsMember(topic.visibility));
} else {
this.activeTopic = this.stakeholder.topics.find(topic => this.isPublicOrIsMember(topic.visibility));
}
this.setSideBar();
this.buildMenu();
this.loading = false;
} else {
this.stakeholder = null;
LinksResolver.resetProperties();
this.navigateToError();
this.buildMenu();
this.loading = false;
}
}));
} else {
this.buildMenu();
if (params && params['topic']) {
this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && this.isPublicOrIsMember(topic.visibility));
} else {
this.activeTopic = this.stakeholder.topics.find(topic => this.isPublicOrIsMember(topic.visibility));
}
this.loading = false;
}
} else {
LinksResolver.resetProperties();
this.stakeholderService.setStakeholder(null);
this.stakeholder = null;
this.buildMenu();
this.loading = false;
}
}
this.subscriptions.push(this.layoutService.isMobile.subscribe(isMobile => {
this.isMobile = isMobile;
this.cdr.detectChanges();
}));
this._route.queryParams.subscribe(params => {
this.view = params['view'];
if(this.stakeholder) {
this.setSideBar();
}
});
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.user = user;
this.updateStakeholder = !this._router.url.includes('user-info');
if (user) {
this.buildMenu();
this.user = user;
if (!this.notificationGroupsInitialized) {
this.setNotificationGroups();
this.setNotificationConfiguration();
}
} else if(this.user) {
this.user = user;
this.notificationGroupsInitialized = false;
this.notificationConfiguration.availableGroups = [];
}
if(this.paramsSubscription) {
this.paramsSubscription.unsubscribe();
}
this.paramsSubscription = this.params.subscribe(params => {
if (this.paramsResolved) {
this.loading = true;
if (params && params['stakeholder']) {
if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder'] || this.updateStakeholder) {
this.subscriptions.push(this.stakeholderService.getStakeholder(params['stakeholder'], this.updateStakeholder).subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = stakeholder;
this.updateStakeholder = false;
LinksResolver.setProperties(this.stakeholder.alias);
this.setProperties(this.stakeholder.alias, this.stakeholder.type);
this.buildMenu();
this.setActives(params);
this.setSideBar();
this.loading = false;
} else {
this.stakeholder = null;
LinksResolver.resetProperties();
this.navigateToError();
this.buildMenu();
this.loading = false;
}
}));
} else {
this.buildMenu();
this.setActives(params);
this.loading = false;
}
} else {
LinksResolver.resetProperties();
this.stakeholderService.setStakeholder(null);
this.stakeholder = null;
this.buildMenu();
this.loading = false;
}
}
});
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.setProjectUpdate(stakeholder);
}))
}));
}
public setNotificationGroups() {
this.notificationGroups = [];
setActives(params: Params) {
if (params && params['topic']) {
this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && this.hasPermission(topic.visibility));
} else {
this.activeTopic = this.stakeholder.topics.find(topic => this.hasPermission(topic.visibility));
}
if(this.activeTopic) {
if (params && params['category']) {
this.activeCategory = this.activeTopic.categories.find(category => category.alias === decodeURIComponent(params['category']) && this.hasPermission(category.visibility));
} else {
this.activeCategory = this.activeTopic.categories.find(category => this.hasPermission(category.visibility));
}
}
}
public setNotificationConfiguration() {
this.notificationConfiguration.entities = this.stakeholderUtils.types.map(option => option.value);
this.notificationConfiguration.service = 'monitor';
this.notificationConfiguration.availableGroups = [];
if (Session.isPortalAdministrator(this.user)) {
this.notificationGroups.push({value: Role.PORTAL_ADMIN, label: 'Portal Administrators'});
this.notificationConfiguration.availableGroups.push({value: Role.PORTAL_ADMIN, label: 'Portal Administrators'});
}
for (let type of this.stakeholderUtils.types) {
if (Session.isCurator(type.value, this.user) || Session.isPortalAdministrator(this.user)) {
this.notificationGroups.push({value: Role.curator(type.value), label: type.label + ' Curators'});
this.notificationConfiguration.availableGroups.push({value: Role.curator(type.value), label: type.label + ' Curators'});
this.notificationConfiguration.availableGroups.push({value: Role.typeManager(type.value), label: type.label + ' Managers'});
this.notificationConfiguration.availableGroups.push({value: Role.typeMember(type.value), label: type.label + ' Members'});
}
}
this.subscriptions.push(this.stakeholderService.getMyStakeholders(this.properties.monitorServiceAPIURL).subscribe(stakeholders => {
stakeholders.forEach(stakeholder => {
this.notificationGroups.push({
this.notificationConfiguration.availableGroups.push({
value: Role.manager(stakeholder.type, stakeholder.alias),
label: stakeholder.name + ' Managers'
});
this.notificationGroups.push({
this.notificationConfiguration.availableGroups.push({
value: Role.member(stakeholder.type, stakeholder.alias),
label: stakeholder.name + ' Members'
});
@ -199,13 +217,29 @@ export class AppComponent implements OnInit, OnDestroy {
this.notificationGroupsInitialized = true;
}));
}
public ngOnDestroy() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
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.userManagementService.clearSubscriptions();
this.layoutService.clearSubscriptions();
this.stakeholderService.clearSubscriptions();
@ -214,22 +248,38 @@ 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 get open() {
return this.layoutService.open;
public removeView() {
this._router.navigate([], {relativeTo: this._route});
}
public login() {
this.userManagementService.login();
}
get isHidden() {
return this.stakeholder && !this.hasPermission(this.view?this.view:this.stakeholder.visibility);
}
get monitorLink() {
return "https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu';
}
private setSideBar() {
let items: MenuItem[] = [];
if (this.isPublicOrIsMember(this.stakeholder.visibility)) {
this.stakeholder.topics.forEach((topic) => {
if (this.isPublicOrIsMember(topic.visibility)) {
let topicItem: MenuItem = new MenuItem(topic.alias, topic.name, "", (
'/' + this.stakeholder.alias + '/' + topic.alias),
if (this.hasPermission(this.view?this.view:this.stakeholder.visibility)) {
this.stakeholder.topics.forEach((topic: Topic) => {
if (this.hasPermission(topic.visibility)) {
let topicItem: MenuItem = new MenuItem(topic.alias, topic.name, "", '/' + this.stakeholder.alias + '/' + topic.alias,
null, [], [], {}, {svg: topic.icon}, null, null, (
'/' + this.stakeholder.alias + '/' + topic.alias));
topicItem.items = topic.categories.filter(category => this.hasPermission(category.visibility)).map(category => {
return new MenuItem(category.alias, category.name, "", ('/' + this.stakeholder.alias + '/' + topic.alias + '/' + category.alias),
null, [], [], {}, {svg: topic.icon}, null, null,
('/' + this.stakeholder.alias + '/' + topic.alias + '/' + category.alias));
});
items.push(topicItem);
}
});
@ -239,17 +289,14 @@ export class AppComponent implements OnInit, OnDestroy {
}
this.adminMenuItems = [];
this.adminMenuItems.push(new MenuItem("general", "General", "", "/admin/" + this.stakeholder.alias, false, [], [], {}, {name: 'badge'}));
this.adminMenuItems.push(new MenuItem("indicators", "Indicators", "", "/admin/" + this.stakeholder.alias + '/indicators', false, [], [], {}, {name: 'bar_chart'}));
this.adminMenuItems.push(new MenuItem("indicators", "Indicators", "", "/admin/" + this.stakeholder.alias + '/indicators', false, [], [], {}, {name: 'bar_chart'}, null, "uk-visible@m"));
if (this.stakeholder.defaultId) {
this.adminMenuItems.push(new MenuItem("users", "Users", "", "/admin/" + this.stakeholder.alias + "/users", false, [], [], {}, {name: 'group'}, null, null, "/admin/" + this.stakeholder.alias + "/users"));
if (Session.isPortalAdministrator(this.user)) {
this.adminMenuItems.push(new MenuItem("admin-tools", "Pages & Entities", "", "/admin/" + this.stakeholder.alias + "/admin-tools/pages", false, [], [], {}, {name: 'description'}, null, null, "/admin/" + this.stakeholder.alias + "/admin-tools"));
this.adminMenuItems.push(new MenuItem("users", "Users", "", "/admin/" + this.stakeholder.alias + "/users", false, [], [], {}, {name: 'group'}, null, "uk-visible@m", "/admin/" + this.stakeholder.alias + "/users"));
if (this.isCurator()) {
this.adminMenuItems.push(new MenuItem("admin-tools", "Pages & Entities", "", "/admin/" + this.stakeholder.alias + "/admin-tools/pages", false, [], [], {}, {name: 'description'}, null, "uk-visible@m", "/admin/" + this.stakeholder.alias + "/admin-tools"));
}
}
this.specialSideBarMenuItem = new MenuItem("back", "Manage profiles", "", "/admin", false, [], null, {}, {
name: 'search',
class: 'uk-text-secondary'
});
this.backItem = new MenuItem("back", "Manage profiles", "", "/admin", false, [], null, {}, {name: 'west'});
this.sideBarItems = items;
this.hasSidebar = this.hasSidebar && this.sideBarItems.length > 0;
}
@ -258,139 +305,132 @@ export class AppComponent implements OnInit, OnDestroy {
this.menuItems = [];
this.userMenuItems = [];
if (this.user) {
if (this.isCurator()) {
if (this.isKindOfMonitorManager()) {
this.userMenuItems.push(new MenuItem("", "Manage profiles",
"", "/admin", false, [], [], {}));
}
if (Session.isPortalAdministrator(this.user)) {
this.userMenuItems.push(new MenuItem("adminOptions", "Super Admin options", "", "/admin/admin-tools/portals", false, [], [], {}));
this.userMenuItems.push(new MenuItem("monitorOptions", "Monitor portal options", "", "/admin/monitor/admin-tools/pages", false, [], [], {}));
this.userMenuItems.push(new MenuItem("adminOptions", "Super Admin options", "", "/admin/admin-tools/portals", false, [], [], {},null, null, "uk-visible@m"));
}
if (this.isCurator()) {
this.userMenuItems.push(new MenuItem("monitorOptions", "Monitor options", "", "/admin/monitor/admin-tools/pages", false, [], [], {},null, null, "uk-visible@m"));
}
}
if (this.stakeholder) {
this.userMenuItems.push(new MenuItem("", "User information", "", "/" + this.stakeholder.alias + "/user-info", false, [], [], {}));
this.menuItems.push({
rootItem: new MenuItem("dashboard", "Dashboard",
"", "/" + this.stakeholder.alias, false, [], null, {}
, null, null, null, null), items: []
});
if (this.isPublicOrIsMember(this.stakeholder.visibility)) {
this.menuItems.push({
rootItem: new MenuItem("search", "Search", "", this.properties.searchLinkToResults,
if (this.hasPermission((this.view && this.isManager(this.stakeholder))?this.view:this.stakeholder.visibility)) {
this.menuItems.push(
new MenuItem("dashboard", "Dashboard",
"", "/" + this.stakeholder.alias, false, [], null, {}
, null, null, null, null)
);
this.menuItems.push(
new MenuItem("search", "Browse Data", "", this.properties.searchLinkToResults,
false, [], null, {resultbestaccessright: '"' + encodeURIComponent("Open Access") + '"'},
null, null, null, null),
items: []
});
this.menuItems.push({
rootItem: new MenuItem("methodology", "Methodology",
"", "/" + this.stakeholder.alias + "/methodology", false, [], null, {}), items: [
new MenuItem("methodology", "Terminology and construction",
"", "/" + this.stakeholder.alias + "/methodology", false, [], null, {}),
new MenuItem("methodology", "See how it works",
"", "/" + this.stakeholder.alias + "/methodology", false, [], null, {}, null, "how"),
]
});
null, null, null, null)
);
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({
rootItem: new MenuItem("develop", "Develop",
"", "/" + this.stakeholder.alias + "/develop", false, [], null, {}), items: []
});
this.menuItems.push(
new MenuItem("develop", "Develop",
"", "/" + this.stakeholder.alias + "/develop", false, [], null, {})
);
}
}
if (this.isManager(this.stakeholder)) {
this.menuItems.push({
rootItem: new MenuItem("manage", "Manage",
this.menuItems.push(
new MenuItem("manage", "Manage",
"", "/admin/" + this.stakeholder.alias, false, [], null, {}
, null, null, null, null), items: []
});
, null, null, "uk-visible@m", null)
);
}
if (!this.hasAdminMenu && this.isFrontPage) {
this.menuHeader = {
route: "/" + this.stakeholder.alias,
route: './' + this.stakeholder.alias,
url: null,
title: this.stakeholder.name,
logoUrl: 'assets/common-assets/logo-services/monitor/small-inverted.svg',
logoSmallUrl: "assets/common-assets/logo-services/monitor/small-inverted.svg",
position: 'center',
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 Dashboard</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">' + this.stakeholder.name + '</div></div>',
position: 'left',
badge: true,
stickyAnimation: true,
menuPosition: "center"
};
} else {
this.menuHeader = {
route: "/" + this.stakeholder.alias,
route: './' + this.stakeholder.alias,
url: null,
title: this.stakeholder.name,
logoUrl: 'assets/common-assets/logo-services/monitor/small.svg',
logoSmallUrl: "assets/common-assets/logo-services/monitor/small.svg",
position: 'center',
badge: false,
stickyAnimation: true,
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 Dashboard</div>' +
'<div class="uk-h6 uk-text-truncate uk-margin-remove">' + this.stakeholder.name + '</div></div>',
position: 'left',
badge: true,
menuPosition: "center"
};
}
} else {
if (this.isFrontPage || !this.hasAdminMenu) {
this.userMenuItems.push(new MenuItem("", "User information", "https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu/user-info', '', false, [], [], {}, null, null, null, null, "_self"));
this.menuHeader = {
route: null,
url: "https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu',
title: "Monitor",
logoUrl: 'assets/common-assets/logo-services/monitor/main.svg',
logoSmallUrl: "assets/common-assets/logo-services/monitor/small.svg",
position: 'left',
badge: true,
stickyAnimation: true,
menuPosition: "center"
};
this.menuItems.push({
rootItem: new MenuItem("about", "About",
"https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu/about/learn-how', "", false, [], null, {}, null, null, null, null, "_self"),
items: []
});
this.menuItems.push({
rootItem: new MenuItem("browse", "Browse",
"https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu/browse', "", false, [], null, {}, null, null, null, null, "_self"),
items: []
});
} else {
this.userMenuItems.push(new MenuItem("", "User information", "", "/admin/user-info", false, [], [], {}));
this.menuHeader = {
route: "/",
url: null,
title: "Monitor Dashboard",
logoUrl: null,
logoSmallUrl: null,
position: 'center',
badge: false,
stickyAnimation: true,
menuPosition: "center"
};
this.userMenuItems.push(new MenuItem("", "User information", this.monitorLink + '/user-info', '', false, [], [], {}, null, null, null, null, "_self"));
this.menuHeader = {
route: null,
url: "https://" + (this.properties.environment == 'beta' ? 'beta.' : '') + 'monitor.openaire.eu',
title: "Monitor",
logoUrl: 'assets/common-assets/logo-services/monitor/main.svg',
logoSmallUrl: "assets/common-assets/logo-services/monitor/small.svg",
position: 'left',
badge: true,
menuPosition: "center"
};
this.menuItems.push(
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);
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.specialSideBarMenuItem = null;
this.backItem = null;
this.adminMenuItems.push(new MenuItem("stakeholders", "Manage profiles", "", "/admin", false, [], [], {}, {name: 'settings'}));
if (Session.isPortalAdministrator(this.user)) {
this.adminMenuItems.push(new MenuItem("super_admin", "Super Admin Options", "", "/admin/admin-tools/portals", false, [], [], {}, {name: 'settings'}, null, null, '/admin/admin-tools'));
this.adminMenuItems.push(new MenuItem("monitor", "Monitor Options", "", "/admin/monitor/admin-tools/pages", false, [], [], {}, {name: 'settings'}, null, null, '/admin/monitor/admin-tools'));
this.adminMenuItems.push(new MenuItem("adminOptions", "Super Admin options", "", "/admin/admin-tools/portals", false, [], [], {}, {name: 'settings'}, null, "uk-visible@m", '/admin/admin-tools'));
}
this.hasAdminMenu = this.hasAdminMenu && this.adminMenuItems.length > 0;
if (Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user)) {
this.adminMenuItems.push(new MenuItem("monitorOptions", "Monitor options", "", "/admin/monitor/admin-tools/pages", false, [], [], {}, {name: 'settings'}, null, "uk-visible@m", '/admin/monitor/admin-tools'));
}
this.hasAdminMenu = this.hasAdminMenu && this.adminMenuItems.length > 1;
}
}
}
public isCurator() {
return this.user && (Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user));
}
public isKindOfMonitorManager() {
return this.user && (Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user) || Session.isKindOfMonitorManager(this.user));
}
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 isPublicOrIsMember(visibility: Visibility): boolean {
return !(visibility == "PRIVATE" || (this.isViewPublic && visibility != "PUBLIC"));
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);
}
}
setProperties(id, type = null) {
@ -400,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,8 +1,8 @@
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";
import {BrowserModule, BrowserTransferStateModule} from '@angular/platform-browser';
import {BrowserModule} from '@angular/platform-browser';
import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
import {AppComponent} from './app.component';
import {OpenaireErrorPageComponent} from './error/errorPage.component';
@ -21,12 +21,18 @@ 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";
import {
NotificationsSidebarModule
} from "./openaireLibrary/notifications/notifications-sidebar/notifications-sidebar.module";
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,
@ -37,14 +43,14 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard";
NavigationBarModule,
BottomModule,
CookieLawModule,
BrowserModule.withServerTransition({ appId: 'serverApp' }),
BrowserModule,
AppRoutingModule,
BrowserTransferStateModule,
SideBarModule, Schema2jsonldModule, RoleVerificationModule, LoadingModule, NotificationsSidebarModule
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,
@ -63,4 +69,7 @@ import {LoginGuard} from "./openaireLibrary/login/loginGuard.guard";
})
//
export class AppModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([incognito])
}
}

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',
@ -67,28 +68,33 @@ import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"
<div>
<div>Request examples for {{openaireEntities.RESULTS | lowercase}}:</div>
<ul class="uk-list uk-list-large uk-list-bullet uk-list-primary">
<li>
<span>Access all </span><span class="uk-text-bolder">{{openaireEntities.RESULTS}}</span> ({{openaireEntities.PUBLICATIONS}}, {{openaireEntities.DATASETS}}, {{openaireEntities.SOFTWARE}}, {{openaireEntities.OTHER}})<br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="">https://api.openaire.eu/search/researchProducts?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span>Access </span><span class="uk-text-bolder">{{openaireEntities.PUBLICATIONS}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="">https://api.openaire.eu/search/publications?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span class="uk-text-bold">Access {{openaireEntities.PUBLICATIONS}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="">https://api.openaire.eu/search/publications?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span class="uk-text-bold">Access Open Access {{openaireEntities.PUBLICATIONS}}</span><br>
<span>Access </span><span class="uk-text-bolder">Open Access {{openaireEntities.PUBLICATIONS}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="uk-text-break">http://api.openaire.eu/search/publications?funder={{stakeholder.index_shortName}}&OA=true</span>
</li>
<li>
<span class="uk-text-bold">Access {{openaireEntities.DATASETS}}</span><br>
<span>Access </span><span class="uk-text-bolder">{{openaireEntities.DATASETS}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="uk-text-break">https://api.openaire.eu/search/datasets?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span class="uk-text-bold">Access {{openaireEntities.SOFTWARE}}</span><br>
<span>Access </span><span class="uk-text-bolder">{{openaireEntities.SOFTWARE}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="uk-text-break">https://api.openaire.eu/search/software?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span class="uk-text-bold">Access {{openaireEntities.OTHER}}</span><br>
<span>Access </span><span class="uk-text-bolder">{{openaireEntities.OTHER}}</span><br>
<span class="uk-text-bold uk-margin-small-right">GET</span>
<span class="uk-text-break">https://api.openaire.eu/search/other?funder={{stakeholder.index_shortName}}</span>
</li>
@ -98,11 +104,11 @@ import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"
<div>Request examples for {{openaireEntities.PROJECTS | lowercase}}:</div>
<ul class="uk-list uk-list-large uk-list-bullet uk-list-primary">
<li>
<span class="uk-text-bold">For the Selective Access</span><br>
<span>For the </span><span class="uk-text-bolder">Selective Access</span><br>
<span class="uk-text-break">https://api.openaire.eu/search/projects?funder={{stakeholder.index_shortName}}</span>
</li>
<li>
<span class="uk-text-bold">For the Bulk Access</span><br>
<span>For the </span><span class="uk-text-bolder">Bulk Access</span><br>
<span class="uk-text-bold uk-text-nowrap">DSpace endpoint:</span>
<span class="uk-text-break uk-margin-small-left">https://api.openaire.eu/projects/dspace/{{stakeholder.index_shortName}}/ALL/ ALL</span><br>
<span class="uk-text-bold uk-text-nowrap">ePrints endpoint:</span>
@ -113,8 +119,7 @@ import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"
</div>
</div>
</div>
`,
styleUrls: ['develop.component.css']
`
})
export class DevelopComponent implements OnInit, OnDestroy {
@ -128,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) {
}
@ -149,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;
}
.uk-border-circle > img {
max-width: 64px;
max-height: 64px;
}

View File

@ -1,393 +0,0 @@
import {Component, Input, OnDestroy, ViewChild} from "@angular/core";
import {Stakeholder} from "../../openaireLibrary/monitor/entities/stakeholder";
import {FormBuilder, FormGroup, 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.css']
})
export class EditStakeholderComponent implements OnDestroy {
@Input()
public disableAlias: boolean = false;
public stakeholderFb: FormGroup;
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 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: FormBuilder,
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) {
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);
}, error => {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
if (errorCallback) {
errorCallback(error)
}
}));
} 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);
}, error => {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
console.error(error);
}));
}
}
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,32 +0,0 @@
<div page-content (stickyEmitter)="stickyPageHeader = $event">
<div header *ngIf="stakeholder">
<div class="uk-flex uk-flex-middle uk-margin-top uk-margin-bottom info" [class.uk-active]="stickyPageHeader">
<img [src]="stakeholder | logoUrl" class="uk-margin-right uk-blend-multiply">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">Admin Dashboard - Manage Profile</div>
<h1 class="uk-h4 uk-margin-remove">{{stakeholder.name}}<span *ngIf="editStakeholderComponent && editStakeholderComponent.dirty && !loading" class="uk-text-large"> (unsaved changes)</span></h1>
</div>
</div>
</div>
<div inner>
<div *ngIf="stakeholder" class="uk-container">
<div class="uk-margin-top 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 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,74 +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} 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;
public stickyPageHeader: boolean = false;
constructor(private stakeholderService: StakeholderService,
private title: Title) {
}
ngOnInit() {
this.loading = true;
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.stakeholder = stakeholder;
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,36 +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";
@NgModule({
declarations: [GeneralComponent],
imports: [
GeneralRoutingModule,
CommonModule,
RouterModule,
InputModule,
LoadingModule,
AlertModalModule,
ReactiveFormsModule,
EditStakeholderModule,
PageContentModule,
LogoUrlPipeModule
],
providers: [
PreviousRouteRecorder,
],
exports: [GeneralComponent]
})
export class GeneralModule {
}

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 {ManageStakeholdersComponent} from "./manageStakeholders.component";
@NgModule({
imports: [
RouterModule.forChild([
{
path: '',
component: ManageStakeholdersComponent,
canDeactivate: [PreviousRouteRecorder],
data: {hasSidebar: true}
}
])
]
})
export class ManageStakeholdersRoutingModule {
}

View File

@ -1,127 +0,0 @@
<div page-content (stickyEmitter)="stickyPageHeader = $event">
<div header>
<div class="uk-flex uk-flex-middle uk-margin-top info" [class.uk-active]="stickyPageHeader">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">
Admin Dashboard - Manage profiles
</div>
<h1 class="uk-h4 uk-margin-remove">Profile Templates & Profiles</h1>
</div>
</div>
<ul *ngIf="isCurator()" class="uk-tab uk-margin-top" uk-tab>
<li [class.uk-active]="tab === 'all'"><a (click)="tab = 'all'">All</a></li>
<li [class.uk-active]="tab === 'templates'"><a (click)="tab = 'templates'">Profile templates</a></li>
<li [class.uk-active]="tab === 'profiles'"><a (click)="tab = 'profiles'">Profiles</a></li>
</ul>
</div>
<div inner>
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-wrap uk-flex-middle uk-margin-top">
<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 *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">
<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 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);">
<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
id="edit_modal" [large]="true" classTitle="uk-background-primary uk-light"
(alertOutput)="editStakeholderComponent.save(callback)"
[okDisabled]="editStakeholderComponent.disabled">
<div class="uk-padding">
<edit-stakeholder #editStakeholderComponent></edit-stakeholder>
</div>
</modal-alert>
<modal-alert #deleteStakeholderModal [overflowBody]="false" (alertOutput)="deleteStakeholder()"></modal-alert>

View File

@ -1,287 +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 {FormBuilder, FormGroup} 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"
})
export class ManageStakeholdersComponent implements OnInit, OnDestroy {
public properties: EnvProperties;
public loading: boolean = true;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public defaultStakeholders: Stakeholder[];
public stakeholders: Stakeholder[];
public alias: string[];
public stakeholder: Stakeholder;
public index: number;
public user = null;
public stickyPageHeader: boolean = false;
public tab: Tab = 'all';
public stakeholderEntities = StakeholderEntities;
/**
* Filtered Stakeholders
*/
public displayDefaultStakeholders: Stakeholder[];
public displayStakeholders: Stakeholder[];
/**
* Top filters
*/
public filters: FormGroup;
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: FormBuilder) {
}
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;
}));
this.subscriptions.push(UIkit.util.on(document, 'hidden', '#edit_modal', (): void => {
this.editStakeholderComponent.removePhoto();
}));
}
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.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.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.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.message = 'This stakeholder will permanently be deleted. Are you sure you want to proceed?';
this.deleteStakeholderModal.open();
}
public deleteStakeholder() {
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);
}, error => {
UIkit.notification('An error has occurred. Please try again later', {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
}));
}
changeStakeholderStatus(stakeholder: Stakeholder, visibility: Visibility) {
let path = [
stakeholder._id
];
this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => {
stakeholder.visibility = 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,44 +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";
@NgModule({
declarations: [ManageStakeholdersComponent],
imports: [
ManageStakeholdersRoutingModule,
CommonModule,
RouterModule,
InputModule,
LoadingModule,
AlertModalModule,
ReactiveFormsModule,
EditStakeholderModule,
IconsModule,
PageContentModule,
LogoUrlPipeModule,
SearchInputModule
],
providers: [
PreviousRouteRecorder,
],
exports: [ManageStakeholdersComponent]
})
export class ManageStakeholdersModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([earth, incognito, restricted]);
}
}

View File

@ -1,466 +0,0 @@
import {Component, OnDestroy, OnInit} from "@angular/core";
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
import {Stakeholder} from "../openaireLibrary/monitor/entities/stakeholder";
import {Subscription} from "rxjs";
import {Meta, Title} from "@angular/platform-browser";
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
import {properties} from "../../environments/environment";
import {ActivatedRoute, Router} from "@angular/router";
import {OpenaireEntities} from "../openaireLibrary/utils/properties/searchFields";
@Component({
selector: 'methodology',
template: `
<div class="uk-section">
<div class="uk-container uk-container-large">
<h1>Terminology and <br> construction<span class="uk-text-primary">.</span></h1>
</div>
<div class="uk-section uk-container uk-container-large">
<ul class="uk-tab" uk-tab>
<li>
<a>Entities</a>
</li>
<li>
<a>Inherited and Inferred Attributes</a>
</li>
<li>
<a>Constructed Attributes</a>
</li>
</ul>
<ul class="uk-switcher">
<li>
<dl class="uk-description-list uk-description-list-divider">
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1 uk-text-primary">{{openaireEntities.RESULTS}}</dt>
<dd class="uk-width-expand">
<div>There are currently four different types of {{openaireEntities.RESULTS | lowercase}} in the OpenAIRE Research <br> Graph:</div>
<ul class="uk-list uk-list-bullet uk-list-primary">
<li>{{openaireEntities.PUBLICATIONS}}</li>
<li>{{openaireEntities.DATASETS}}</li>
<li>{{openaireEntities.SOFTWARE}}</li>
<li>{{openaireEntities.OTHER}}.</li>
</ul>
<div class="uk-margin-small-top">
OpenAIRE deduplicates (merges) different records of {{openaireEntities.RESULTS | lowercase}} and keeps the <br> metadata of all instances.
</div>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">{{openaireEntities.PUBLICATION}}</dt>
<dd class="uk-width-expand">
{{openaireEntities.RESULTS}} intended for human reading (published articles, pre-prints, conference <br> papers, presentations, technical reports, etc.)
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">{{openaireEntities.DATASET}}</dt>
<dd class="uk-width-expand">
<!-- <div>{{openaireEntities.DATASET}}</div>-->
<div>Granularity is not defined by OpenAIRE, it reflects the granularity supported by
the sources <br> from which the description of the {{openaireEntities.DATASET | lowercase}} has been collected.</div>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">{{openaireEntities.SOFTWARE_SINGULAR}}</dt>
<dd class="uk-width-expand">
Source code or software package developed and/or used in a research context
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">{{openaireEntities.OTHER_SINGULAR}}</dt>
<dd class="uk-width-expand">
Anything that does not fall in the previous categories (e.g. workflow, methods, protocols)
</dd>
</div>
</dl>
</li>
<li>
<div class="uk-text-center uk-padding">
The attributes of entities listed below are either inherited via entries in the harvested metadata records or automatically generated by our inference (text and data mining) algorithms.
</div>
<hr>
<dl class="uk-description-list uk-description-list-divider">
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">{{openaireEntities.ORGANIZATION}}</dt>
<dd class="uk-width-expand">
<p><span class="uk-text-bold">For {{openaireEntities.RESULTS | lowercase}},</span> this refers to the affiliated organizations of its authors</p>
<p><span class="uk-text-bold">For {{openaireEntities.PROJECTS | lowercase}}:</span> the {{openaireEntities.ORGANIZATIONS | lowercase}} participating in the {{openaireEntities.PROJECT | lowercase}}
(i.e. beneficiaries of the grant)</p>
<p>The OpenAIRE research graph is in the process of improving the {{openaireEntities.ORGANIZATION | lowercase}} database (disambiguation) with the newly developed <a href="https://www.openaire.eu/blogs/openorgs-bridging-registries-of-research-organisations" target="_blank">OpenOrgs</a> tool.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Country</dt>
<dd class="uk-width-expand">
<p>The country of the {{openaireEntities.ORGANIZATION | lowercase}}. </p>
<p>
<span class="uk-text-bold">Country code mapping: </span>
<a href="https://api.openaire.eu/vocabularies/dnet:countries" target="_blank">
https://api.openaire.eu/vocabularies/dnet:countries</a>
</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Funder</dt>
<dd class="uk-width-expand">
<p>Funders that have joined OpenAIRE, i.e. their {{openaireEntities.PROJECT | lowercase}} data have gone through a validation process.</p>
<p>You can visit <a class="https://explore.openaire.eu/search/find" target="_blank">https://explore.openaire.eu/search/find</a> if you would like to explore the {{openaireEntities.RESULTS | lowercase}} and {{openaireEntities.PROJECTS | lowercase}} of all funders in OpenAIRE (the list of funders can be seen under the "Funder" Filter shown on the left side of the page).</p>
<p><span class="uk-text-bold">To join: </span><a href="https://www.openaire.eu/funders-how-to-join-guide" target="_blank">https://www.openaire.eu/funders-how-to-join-guide</a></p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Type</dt>
<dd class="uk-width-expand">
<p>The sub-type of a {{openaireEntities.RESULT | lowercase}} (e.g., a {{openaireEntities.PUBLICATION | lowercase}} can be a pre-print, conference proceeding,
article,
etc.)</p>
<p><span class="uk-text-bold">Resource type mapping: </span>
<a href="https://api.openaire.eu/vocabularies/dnet:result_typologies" target="_blank">https://api.openaire.eu/vocabularies/dnet:result_typologies</a>
(click on the code to see the specific types for each result type)
</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Access mode or access rights</dt>
<dd class="uk-width-expand">
<p>The best available (across all instances) access rights of a {{openaireEntities.RESULT | lowercase}}</p>
<p>Types: open, restricted, closed, embargo (= closed for a specific period of time, then open)</p>
<p><span class="uk-text-bold">Note:</span> definition of <span class="uk-text-bold">restricted</span>
may vary by data source, it may refer to access rights being given to registered users, potentially behind a paywall.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">CC license</dt>
<dd class="uk-width-expand">
<p>A Creative Commons copyright license <a href="(https://creativecommons.org/)" target="_blank">(https://creativecommons.org/)</a></p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">PID (persistent identifier)</dt>
<dd class="uk-width-expand">
<p>A long-lasting reference to a resource</p>
<p><span class="uk-text-bold">Types: </span> <a
href="http://api.openaire.eu/vocabularies/dnet:pid_types" target="_blank">http://api.openaire.eu/vocabularies/dnet:pid_types</a>
</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Context</dt>
<dd class="uk-width-expand">
Related {{openaireEntities.COMMUNITY | lowercase}}, initiative or infrastructure.
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Journal</dt>
<dd class="uk-width-expand">
The scientific journal an article is published in.
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Publisher</dt>
<dd class="uk-width-expand">
The publisher of the venue (journal, book, etc.) of a {{openaireEntities.RESULT | lowercase}}.
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1 uk-text-primary">{{openaireEntities.DATASOURCES}}</dt>
<dd class="uk-width-expand">
<p>The different data sources ingested in the OpenAIRE Research Graph.</p>
<div class="uk-text-bold">Data Source Types:</div>
<ul class="uk-list uk-list-disc">
<li>Repositories</li>
<li>Open Access Publishers & Journals</li>
<li>Aggregators</li>
<li>Entity Registries</li>
<li>Journal Aggregators</li>
<li>CRIS (Current Research Information System)</li>
</ul>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Repositories</dt>
<dd class="uk-width-expand">
Information systems where scientists upload the bibliographic metadata and payloads of their
{{openaireEntities.RESULTS | lowercase}} (e.g. PDFs of their scientific articles, CSVs of their data, archive with their
software), due to obligations from their {{openaireEntities.ORGANIZATIONS | lowercase}}, their funders, or due to community practices
(e.g. ArXiv, Europe PMC, Zenodo).
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Open Access Publishers & Journals</dt>
<dd class="uk-width-expand">
Information systems of open access publishers or relative journals, which offer bibliographic
metadata and PDFs of their published articles.
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Aggregators</dt>
<dd class="uk-width-expand">
Information systems that collect descriptive metadata about {{openaireEntities.RESULTS | lowercase}} from multiple sources
in order to enable cross-data source discovery of given {{openaireEntities.RESULTS | lowercase}} (e,g, DataCite,
BASE, DOAJ).
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">Entity Registries</dt>
<dd class="uk-width-expand">
Information systems created with the intent of maintaining authoritative registries of given
entities in the scholarly communication, such as OpenDOAR for the institutional repositories, re3data
for the data repositories, CORDA and other funder databases for {{openaireEntities.PROJECTS | lowercase}} and funding information.
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-5@m uk-width-1-1">CRIS (Current Research Information System)</dt>
<dd class="uk-width-expand">
Information systems adopted by research and academic {{openaireEntities.ORGANIZATIONS | lowercase}} to keep track of their research
administration records and relative results; examples of CRIS content are articles or {{openaireEntities.DATASETS | lowercase}} funded
by {{openaireEntities.PROJECTS | lowercase}}, their principal investigators, facilities acquired thanks to funding, etc.
</dd>
</div>
</dl>
</li>
<li>
<div class="uk-text-center uk-padding">
The attributes of entities under this tab are constructed following the methodology described below.
</div>
<hr>
<dl class="uk-description-list uk-description-list-divider">
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Attribute</dt>
<dd class="uk-width-1-3@m uk-width-1-1 uk-text-bold">Definition</dd>
<dd class="uk-width-1-3@m uk-width-1-1 uk-text-bold">Construction</dd>
</div>
<hr>
<div class="uk-padding-small uk-text-bold uk-text-primary">
Journal Business Models
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Fully Open Access (OA)</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>A journal that publishes only in open access.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>We construct the list of fully OA journals using Unpaywall data. </p>
<p>In brief, a journal is fully OA if </p>
<ol>
<li>It is in the Directory of Open Access Journals (DOAJ) </li>
<li>It has a known (curated list) fully OA Publisher. </li>
<li>It only publishes OA articles. </li>
</ol>
<p><a href="https://support.unpaywall.org/support/solutions/articles/44001792752-how-do-we-decide-if-a-given-journal-is-fully-oa-" target="_blank">More information</a></p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Subscription</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>A journal that charges for access to its articles.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Journals without any open access articles.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Hybrid</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>A subscription journal where some of its articles are open access.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Journals with open access articles that are not fully OA journals are hybrid.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Transformative</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>"A Transformative Journal is a subscription/hybrid journal that is actively committed to transitioning to a fully Open Access journal.</p>
<p>In addition, a Transformative Journal must:</p>
<ul>
<li>gradually increase the share of Open Access content; and</li>
<li>offset subscription income from payments for publishing services (to avoid double payments)."</li>
</ul>
<p>Source:</p>
<p><a href="https://www.coalition-s.org/transformative-journals-faq/" target="_blank">https://www.coalition-s.org/transformative-journals-faq/</a></p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Transformative Journals are identified by ISSN matching with the publicly available Transformative Journals data (<a href="https://journalcheckertool.org/transformative-journals/" target="_blank">https://journalcheckertool.org/transformative-journals/</a>)</p>
</dd>
</div>
<hr>
<div class="uk-padding-small uk-text-bold uk-text-primary">
Journal APC Business Models
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Diamond OA</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>A fully OA journal that does not charge article processing charges (APCs).</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>APC information is obtained from DOAJ using DOAJs exportable version of the journal metadata (<a href="https://doaj.org/docs/public-data-dump/" target="_blank">https://doaj.org/docs/public-data-dump/</a>). We used it to determine whether a particular fully OA journal charges APCs. </p>
</dd>
</div>
<hr>
<div class="uk-padding-small uk-text-bold uk-text-primary">
Routes to Open Access (OA)
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Green OA</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>An open access scientific publication deposited in a repository</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>As in definition</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Gold OA</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>A scientific publication published in a fully OA journal.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Fully OA journals are defined above.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Hybrid OA</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>An open access scientific publication published in a hybrid journal with an open license.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Hybrid journals are defined above.</p>
<p>At this point we consider only CC licenses open, we are currently working on cleaning non-CC licenses as well to identify other open ones.</p>
<p>In principle, this means that we may be underestimating the number of hybrid OA articles and overestimating the number of bronze.</p>
</dd>
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Bronze OA</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>An open access scientific publication published in a hybrid journal without an open license.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
</dd>
</div>
<hr>
<div class="uk-padding-small uk-text-bold uk-text-primary">
Miscellaneous
</div>
<hr>
<div class="uk-grid uk-padding-small" uk-grid>
<dt class="uk-width-1-3@m uk-width-1-1">Downloads</dt>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>The number of downloads of a publications full text in a specific time frame, from a given set of data sources.</p>
</dd>
<dd class="uk-width-1-3@m uk-width-1-1">
<p>Data for downloads is taken from OpenAIREs Usage Counts service that harvests it from a set of repositories. The time range of available downloads varies for each repository.</p>
<p>
<a href="https://www.openaire.eu/guides-usage-counts" target="_blank">More information</a>
</p>
</dd>
</div>
<hr>
</dl>
</li>
</ul>
<div class="uk-margin-medium-top">
<icon name="graph" customClass="text-graph"></icon>
<span class="uk-margin-small-left uk-text-meta">More information for </span>
<a href="https://graph.openaire.eu" class="text-graph">OpenAIRE Research Graph</a>
<span class="uk-text-meta">.</span>
</div>
</div>
<div id="how" class="uk-container uk-container-large uk-section uk-section-small uk-margin-large-top">
<h2 class="uk-h1">
Inclusion, transparency, <br> quality, state of the art <br> technology<span class="uk-text-primary">.</span>
</h2>
<div class="uk-margin-large-top uk-card uk-card-default uk-card-body">
<p class="uk-margin-top">Our methodological approach is based on the following operational quality criteria:</p>
<ul>
<li><span class="uk-text-bold">Openness and transparency:</span> Methodological assumptions are openly and clearly presented.</li>
<li><span class="uk-text-bold">Coverage and accuracy:</span> As detailed in <a href="https://graph.openaire.eu/" target="_blank">graph.openaire.eu</a>
multiple data sources are ingested in the OpenAIRE research graph for coverage to the fullest extent possible, in order to provide meaningful indicators.</li>
<li><span class="uk-text-bold">Clarity and replicability:</span> We describe our construction methodology in detail, so that
it can be verified and used by the scholarly communication community to create ongoing updates to our proposed statistics and indicators.</li>
<li><span class="uk-text-bold">Readiness and timeliness:</span> The methodology is built around well-established open databases
and already tested knowledge extraction technologies - natural language processing (NLP)/machine-learning (ML) - using operational
workflows in OpenAIRE to warrant timely results.</li>
<li><span class="uk-text-bold">Trust and robustness:</span> Our methodology also strives to be reliable, robust, and aligned
to other assessment methods so that it can be operationalized, used and reused, in conjunction with other assessment methods.</li>
</ul>
<div class="uk-text-small uk-text-italic uk-text-right">The text above is modified from <a href="https://op.europa.eu/en/publication-detail/-/publication/56cc104f-0ebb-11ec-b771-01aa75ed71a1"
target="_blank">this report</a> (DOI: 10.2777/268348).</div>
</div>
<div class="uk-margin-large-top uk-padding-small">
<h3 class="uk-h4">Step-by-step</h3>
<how></how>
</div>
</div>
</div>
`,
styleUrls: ['methodology.component.css']
})
export class MethodologyComponent implements OnInit, OnDestroy {
public stakeholder: Stakeholder;
public tab: 'entities' | 'attributes' = 'entities';
private subscriptions: any[] = [];
public openaireEntities = OpenaireEntities;
constructor(private stakeholderService: StakeholderService,
private seoService: SEOService,
private _meta: Meta,
private _router: Router,
private route: ActivatedRoute,
private _title: Title) {
}
ngOnInit() {
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.stakeholder = stakeholder;
if (this.stakeholder) {
/* Metadata */
const url = properties.domain + properties.baseLink + this._router.url;
this.seoService.createLinkForCanonicalURL(url, false);
this._meta.updateTag({content: url}, "property='og:url'");
const description = "Methodology | " + this.stakeholder.name;
const title = "Methodology | " + this.stakeholder.name;
this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'");
this._meta.updateTag({content: title}, "property='og:title'");
this._title.setTitle(title);
}
}));
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
}

View File

@ -1,28 +0,0 @@
import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
import {MethodologyComponent} from "./methodology.component";
import {RouterModule} from "@angular/router";
import {PreviousRouteRecorder} from "../openaireLibrary/utils/piwik/previousRouteRecorder.guard";
import {PageContentModule} from "../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {HowModule} from "../openaireLibrary/monitor/how/how.module";
import {TabsModule} from "../openaireLibrary/utils/tabs/tabs.module";
import {IconsModule} from "../openaireLibrary/utils/icons/icons.module";
import {IconsService} from "../openaireLibrary/utils/icons/icons.service";
import {graph} from "../openaireLibrary/utils/icons/icons";
@NgModule({
declarations: [MethodologyComponent],
imports: [CommonModule, RouterModule.forChild([
{
path: '',
component: MethodologyComponent,
canDeactivate: [PreviousRouteRecorder]
},
]), PageContentModule, HowModule, TabsModule, IconsModule],
exports: [MethodologyComponent]
})
export class MethodologyModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([graph]);
}
}

View File

@ -16,6 +16,14 @@ import {OpenaireErrorPageComponent} from "../error/errorPage.component";
activeMenuItem: "dashboard"
}
},
{
path: ':stakeholder/indicators',
loadChildren: () => import('../openaireLibrary/monitor/indicators/indicators.module').then(m => m.IndicatorsModule),
canDeactivate: [PreviousRouteRecorder],
data: {
hasSidebar: false
}
},
{
path: ':stakeholder/develop',
loadChildren: () => import('../develop/develop.module').then(m => m.DevelopModule),
@ -26,7 +34,7 @@ import {OpenaireErrorPageComponent} from "../error/errorPage.component";
},
{
path: ':stakeholder/methodology',
loadChildren: () => import('../methodology/methodology.module').then(m => m.MethodologyModule),
loadChildren: () => import('../openaireLibrary/monitor/methodology/methodology.module').then(m => m.MethodologyModule),
canDeactivate: [PreviousRouteRecorder],
data: {
hasSidebar: false

View File

@ -1,21 +0,0 @@
.uk-card {
min-height: 270px;
}
.uk-card.semiFiltered, .uk-card.semiFiltered > * > .highcharts-series-group {
opacity: 0.5;
}
.custom-description-overlay {
position: absolute;
top: 0;
left: 0;
background: rgba(0,0,0,0.8);
width: 100%;
height: 100%;
}
.custom-description-overlay .inner {
background: #fff;
border-radius: 6px;
width: 75%;
max-height: 75%;
overflow: auto;
}

View File

@ -1,5 +1,5 @@
<ng-template #selected_filters_pills>
<div class="uk-width-1-1" uk-slider="finite: true">
<div class="uk-slider filters-slider" uk-slider="finite: true">
<div [class.uk-invisible]="list.children.length === 0" class="uk-position-relative">
<div class="uk-slider-container" style="height: 40px">
<ul #list class="uk-slider-items uk-grid uk-grid-small uk-margin-small-right uk-flex-nowrap">
@ -32,50 +32,33 @@
</ng-container>
</ul>
</div>
<div>
<a class="uk-position-center-left-out" uk-slider-item="previous"><span uk-icon="chevron-left"></span></a>
<a class="uk-position-center-right-out" uk-slider-item="next"><span uk-icon="chevron-right"></span></a>
</div>
<slider-arrow type="previous"></slider-arrow>
<slider-arrow type="next"></slider-arrow>
</div>
</div>
</ng-template>
<div page-content (stickyEmitter)="stickyPageHeader = $event">
<div *ngIf="activeTopic && activeTopic.categories.length > 0" header>
<div class="uk-flex uk-flex-middle uk-margin-top info" [class.uk-active]="stickyPageHeader">
<img [src]="stakeholder | logoUrl" class="uk-margin-right uk-blend-multiply">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">Dashboard</div>
<h1 class="uk-h4 uk-margin-remove">{{stakeholder.name}}</h1>
</div>
<div page-content [border]="isMobile">
<div header>
<div *ngIf="stakeholder" class="uk-hidden">
<h1 class="uk-h6 uk-margin-remove">{{stakeholder.name}}</h1>
</div>
<div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" class="uk-margin-top">
<ul class="uk-tab">
<ng-template ngFor [ngForOf]="activeTopic.categories" let-category>
<li *ngIf="isPublicOrIsMember(category.visibility)"
[class.uk-active]="category.alias === activeCategory.alias">
<a [routerLink]="['/', stakeholder.alias, activeTopic.alias, category.alias]"
[queryParams]="queryParams">
<span class="title">{{category.name}}</span>
</a>
</li>
</div>
<div actions>
<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 && !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"
[queryParams]="queryParams" customClass="uk-text-uppercase"
[routerLink]="['/', stakeholder.alias, activeTopic.alias, activeCategory.alias, subCategory.alias]"
[active]="subCategory.alias === activeSubCategory.alias"></slider-tab>
</ng-template>
</ul>
</slider-tabs>
</div>
</div>
<div inner>
<div *ngIf="activeCategory && countSubCategoriesToShow(activeCategory) > 1" class="uk-flex uk-flex-right uk-margin-top">
<ul class="uk-subnav uk-subnav-pill-alt">
<ng-template ngFor [ngForOf]="activeCategory.subCategories" let-subCategory let-i="index">
<li *ngIf="isPublicOrIsMember(subCategory.visibility)"
[ngClass]="(subCategory.alias === activeSubCategory.alias)?'uk-active':''">
<a [routerLink]="['/', stakeholder.alias, activeTopic.alias, activeCategory.alias, subCategory.alias]"
[queryParams]="queryParams"
class="uk-margin-remove-bottom"
><span>{{subCategory.name}}</span></a>
</li>
</ng-template>
</ul>
</div>
<div *ngIf="privateStakeholder" class="message">
<div class="uk-text-center">
<h3 class="uk-flex uk-flex-middle">
@ -85,11 +68,14 @@
</div>
</div>
<div *ngIf="!privateStakeholder && stakeholder" class="uk-section">
<div *ngIf="activeSubCategory?.description" class="uk-margin-medium-bottom">
{{activeSubCategory.description}}
</div>
<div *ngIf="(activeSubCategory && (activeSubCategory.charts.length == 0 || countSectionsWithIndicatorsToShow(activeSubCategory.charts) == 0))
&& ((activeSubCategory && activeSubCategory.description && activeSubCategory.description.length > 0) ||
(activeCategory && activeCategory.description && activeCategory.description.length > 0) ||
(activeTopic && activeTopic.description && activeTopic.description.length > 0))" class="uk-text-center">
<div class="uk-height-small uk-margin-large-top uk-margin-xlarge-right uk-margin-xlarge-left">
<div class="uk-height-small uk-margin-large-top uk-margin-xlarge-right uk-margin-xlarge-left">
{{activeSubCategory && activeSubCategory.description && activeSubCategory.description.length > 0 ? activeSubCategory.description
: (activeCategory && activeCategory.description && activeCategory.description.length > 0 ? activeCategory.description :
(activeTopic.description && activeTopic.description.length > 0 ? activeTopic.description : ""))}}
@ -98,111 +84,150 @@
<ng-template [ngIf]="!loading && !privateStakeholder &&
(!activeSubCategory ||
((activeSubCategory.numbers.length == 0 || countSectionsWithIndicatorsToShow(activeSubCategory.numbers) == 0) &&
(activeSubCategory.charts.length == 0 || countSectionsWithIndicatorsToShow(activeSubCategory.charts) == 0))
(activeSubCategory.charts.length == 0 || countSectionsWithIndicatorsToShow(activeSubCategory.charts) == 0))
|| !activeTopic || !activeCategory || !activeSubCategory)" [ngIfElse]="content">
<div class="message uk-text-center">
<h3>
No indicators available yet. Stay tuned!
Nothing to see here!
</h3>
</div>
</ng-template>
<ng-template #content>
<ng-container *ngFor="let number of activeSubCategory.numbers; let i = index;">
<div *ngIf="countIndicatorsToShow(number.indicators) > 0" class="uk-grid uk-margin-large-bottom" uk-grid
uk-height-match="target: .uk-card">
<h5 *ngIf="number.title" class="uk-width-1-1 uk-margin-bottom">{{number.title}}</h5>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="isPublicOrIsMember(indicator.visibility)" [ngClass]="getNumberClassBySize(indicator.width)"
class="uk-margin-bottom">
<div class="uk-card uk-card-default uk-flex uk-flex-column uk-flex-center"
[class.semiFiltered]="indicator.indicatorPaths[0].filtersApplied < countSelectedFilters()">
<div class="uk-text-center">
<!--<div *ngIf="properties.environment === 'development'">
Filtered:{{indicator.indicatorPaths[0].filtersApplied}}out of{{countSelectedFilters()}}
</div>-->
<div class="number uk-text-bold uk-text-background">
<span *ngIf="numberResults.get(i + '-' + j)">{{numberResults.get(i + '-' + j) | number}}</span>
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
<div *ngIf="countSectionsWithIndicatorsToShow(activeSubCategory.numbers) > 0" class="uk-margin-medium-bottom">
<ng-container *ngFor="let number of activeSubCategory.numbers; let i = index;">
<ng-container *ngIf="!isMobile && countIndicatorsToShow(number.indicators) > 0">
<div class="uk-grid uk-grid-small uk-grid-match uk-margin-medium-bottom" uk-grid
uk-height-match="target: .uk-card">
<h5 *ngIf="number.title" class="uk-width-1-1 uk-margin-bottom">{{number.title}}</h5>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<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.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]="(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)="changeOverlay($event, indicator, 'description')">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
</span>
</a>
</div>
</div>
<div
*ngIf="indicator.overlay && (indicator.description || indicator.additionalDescription)"
click-outside-or-esc class="uk-overflow-auto"
(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)="changeOverlay($event, indicator, false)">
<span class="uk-flex uk-flex-middle">
<icon name="close" type="outlined" [flex]="true"></icon>
</span>
</a>
</div>
<div class="uk-margin-small-top uk-margin-right">
<p *ngIf="indicator.description">
{{indicator.description}}
</p>
<p *ngIf="indicator.additionalDescription">
{{indicator.additionalDescription}}
</p>
</div>
</div>
</div>
<!-- for printing only -->
<span *ngIf="numberResults.get(i + '-' + j)"
class="uk-text-bold uk-hidden">{{numberResults.get(i + '-' + j) | number}}</span>
<!-- ----------------- -->
<div class="uk-text-uppercase uk-text-small uk-margin-top">{{indicator.name}}</div>
</div>
<!-- <div *ngIf="indicator.description || indicator.additionalDescription"
class="uk-overlay uk-position-bottom">
<div class="uk-padding-small">
<div *ngIf="indicator.description">
{{indicator.description}}
</div>
<div *ngIf="indicator.additionalDescription">
{{indicator.additionalDescription}}
</ng-template>
</div>
</ng-container>
<ng-container *ngIf="isMobile && countIndicatorsToShow(number.indicators) > 0">
<h6 *ngIf="number.title" class="uk-width-1-1 uk-margin-bottom">{{number.title}}</h6>
<div class="uk-card uk-card-default uk-padding-small number-card">
<div class="uk-grid uk-grid-small uk-child-width-1-1" uk-grid>
<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.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]="(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>
</div>
</div>
</div> -->
</ng-template>
</div>
</div>
</ng-template>
</div>
</ng-container>
<div [class.uk-margin-large-top]="countSectionsWithIndicatorsToShow(activeSubCategory.numbers) > 0">
<ng-container *ngFor="let chart of activeSubCategory.charts; let i = index;">
<div *ngIf="countIndicatorsToShow(chart.indicators) > 0"
class="uk-grid uk-grid-column-medium uk-margin-medium-bottom uk-flex uk-flex-middle" uk-grid
uk-height-match="target: .uk-card">
<h5 *ngIf="chart.title" class="uk-width-1-1 uk-margin-bottom">{{chart.title}}</h5>
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
<div *ngIf="isPublicOrIsMember(indicator.visibility) && chartsActiveType.get(i + '-' + j)"
[ngClass]="getChartClassBySize(indicator.width)">
<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">
<h4 class="uk-margin-bottom chartTitle uk-flex uk-flex-bottom ">
<div>{{indicator.name + " "}}</div>
</h4>
<div *ngIf="indicator.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of indicator.indicatorPaths;"
class="uk-button"
(click)="setActiveChart(i, j, indicatorPath.type)"
[class.uk-button-secondary]="chartsActiveType.get(i + '-' + j).url === indicatorPath.url">
{{indicatorPath.type}}
</button>
</div>
<!--<div *ngIf="properties.environment === 'development'">
Filtered: {{chartsActiveType.get(i + '-' + j).filtersApplied}} out of
{{countSelectedFilters()}}</div>-->
<iframe
*ngIf=" !properties.disableFrameLoad && chartsActiveType.get(i + '-' + j).source !== 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1 uk-blend-multiply" allowfullscreen="true" mozallowfullscreen="true"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"></iframe>
<div *ngIf="properties.disableFrameLoad && chartsActiveType.get(i + '-' + j).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>
<img *ngIf="chartsActiveType.get(i + '-' + j).source === 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1 uk-blend-multiply"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')">
</ng-container>
</ng-container>
</div>
<ng-container *ngFor="let chart of activeSubCategory.charts; let i = index;">
<div *ngIf="countIndicatorsToShow(chart.indicators) > 0"
class="uk-grid uk-grid-small uk-grid-match uk-margin-medium-bottom uk-flex uk-flex-middle" uk-grid
uk-height-match="target: .uk-card">
<h5 *ngIf="chart.title && !isMobile" class="uk-width-1-1 uk-margin-bottom">{{chart.title}}</h5>
<h6 *ngIf="chart.title && isMobile" class="uk-width-1-1">{{chart.title}}</h6>
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
<div *ngIf="hasPermission(indicator.visibility) && chartsActiveType.get(i + '-' + j)"
[ngClass]="getChartClassBySize(indicator.width)">
<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">
{{indicator.name + " "}}
</h6>
<div *ngIf="indicator.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of indicator.indicatorPaths;"
class="uk-button"
(click)="setActiveChart(i, j, indicatorPath.type)"
[class.uk-button-secondary]="chartsActiveType.get(i + '-' + j).url === indicatorPath.url">
{{indicatorPath.type}}
</button>
</div>
<div *ngIf="indicator.description || indicator.additionalDescription"
class="uk-position-bottom-left uk-margin-left uk-margin-small-bottom">
<a class="uk-display-inline-block uk-button uk-button-text"
(click)="toggleDescriptionOverlay($event, j)">
<span class="uk-flex uk-flex-middle">
<icon name="analytics" type="outlined" [flex]="true"></icon>
<span class="uk-margin-small-left">Description</span>
</span>
</a>
<!--<div *ngIf="properties.environment === 'development'">
Filtered: {{chartsActiveType.get(i + '-' + j).filtersApplied}} out of
{{countSelectedFilters()}}</div>-->
<iframe [class.uk-blend-multiply]="!isFullscreen"
*ngIf=" !properties.disableFrameLoad && chartsActiveType.get(i + '-' + j).source !== 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1" allowfullscreen="true" mozallowfullscreen="true"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"></iframe>
<div *ngIf="properties.disableFrameLoad && chartsActiveType.get(i + '-' + j).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="showDescriptionOverlay[j] && (indicator.description || indicator.additionalDescription)"
class="custom-description-overlay uk-card uk-card-default uk-flex uk-flex-middle uk-flex-center">
<div class="inner uk-padding-small" click-outside-or-esc
(clickOutside)="closeDescriptionOverlay($event, j)">
<img *ngIf="chartsActiveType.get(i + '-' + j).source === 'image'"
[src]="chartsActiveType.get(i + '-' + j).safeResourceUrl"
class="uk-width-1-1 uk-blend-multiply"
[ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')">
</div>
<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.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, j)">
<button class="uk-close uk-icon" (click)="changeOverlay($event, indicator, false)">
<icon name="close" ratio="1"></icon>
</button>
</div>
@ -218,38 +243,47 @@
</div>
</div>
</div>
<div class="printGap uk-hidden"></div>
</ng-template>
</div>
</ng-container>
</div>
<div class="uk-margin-medium-top uk-text-small uk-flex hideInfo">
<!-- Last Stats Date-->
<div class="uk-width-2-3@m uk-width-1-2">
<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>
<span *ngIf="statsUpdateDate" class="uk-text-baseline uk-text-meta">
. Last update of statistics in OpenAIRE: {{statsUpdateDate | date: 'MMM dd, yyyy'}}
</span>
</div>
<div class="printGap uk-hidden"></div>
</ng-template>
</div>
<!--Feedback-->
<div class="uk-width-expand uk-text-right">
<span class="uk-text-meta">Send us your </span>
<a class="uk-link" [href]="feedback" target="_self">feedback</a>
<span class="uk-text-meta">.</span>
</div>
</div>
</ng-container>
</ng-template>
</div>
</div>
<div sticky_footer class="uk-visible@m">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div>
<ng-template #graph_and_feedback_template>
<div *ngIf="!view" class="uk-margin-small-top uk-margin-small-bottom uk-grid uk-grid-small uk-text-small hideInfo"
uk-grid>
<!-- Last Stats Date-->
<div class="uk-width-expand@m uk-width-1-1">
<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">
<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">
<span class="uk-text-meta">Send us your </span>
<a class="uk-link" [href]="feedback" target="_self">feedback</a>
<span class="uk-text-meta">.</span>
</div>
</div>
</ng-template>
</div>
<!--(click)="filterToggle= !filterToggle"
[style.display]="(filterToggle?'none':'inherit')"-->
<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>
</div>
<span [class.uk-hidden]="countSelectedFilters() === 0"
class="uk-offcanvas-count uk-flex uk-flex-middle uk-flex-center">
{{countSelectedFilters()}}
</span>
</a>
<div *ngIf="stakeholder && !privateStakeholder" id="style_switcher" class="uk-offcanvas"
uk-offcanvas="flip:true; overlay: true">
<div class="uk-offcanvas-bar">
@ -259,19 +293,16 @@
</button>
</div>
<div>
<div class="uk-grid uk-flex uk-flex-middle">
<h4>Filters</h4>
<a *ngIf="countSelectedFilters() > 1"
class="uk-text-small uk-width-1-2" (click)="clearAll()"> Clear All </a>
</div>
<div class="uk-grid uk-grid-small" uk-grid>
<ng-container *ngTemplateOutlet="selected_filters_pills; context: {margin:false}"></ng-container>
<div class="uk-flex uk-flex-middle uk-margin-bottom">
<h4 class="uk-margin-remove-bottom">Filters</h4>
<a *ngIf="countSelectedFilters() > 1" class="uk-text-small uk-margin-left" (click)="clearAll()"> Clear All </a>
</div>
<ng-container *ngTemplateOutlet="selected_filters_pills"></ng-container>
<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 [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">
@ -280,14 +311,14 @@
</li>
</ng-container>
</ul>
<div *ngIf="user || countSelectedFilters() > 0 " class="uk-margin-medium-top uk-alert uk-alert-primary">
If your filter selection cannot be applied to a chart, that chart will appear grayed-out.
</div>
<i *ngIf="user || countSelectedFilters() > 0 " class="uk-margin-medium-top uk-text-small uk-display-block">
<sup>*</sup> If your filter selection cannot be applied to a chart, that chart will appear grayed-out.
</i>
</div>
</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

@ -0,0 +1,7 @@
@import (reference) "~src/assets/openaire-theme/less/_import-variables";
&.semiFiltered {
&, & > * > .highcharts-series-group {
opacity: 0.5;
}
}

View File

@ -1,105 +1,47 @@
import {ChangeDetectorRef, Component, OnDestroy, OnInit, 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, StakeholderUtils} 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 {FormBuilder, FormControl} from "@angular/forms";
import {Subscriber, Subscription} from "rxjs";
import {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';
declare var UIkit;
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.css']
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 isViewPublic: boolean = false;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
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: FormControl;
public statsUpdateDate: Date;
public stickyPageHeader: boolean = false;
public showDescriptionOverlay: boolean[] = [];
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: FormBuilder, 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() {
@ -110,14 +52,11 @@ export class MonitorComponent implements OnInit, OnDestroy {
}
}));
}
this.keyword = this._fb.control('');
this.subscriptions.push(this.keyword.valueChanges.subscribe(value => {
//TODO do a real action
}));
let subscription: Subscription;
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;
@ -125,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 => {
@ -163,38 +100,20 @@ 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.title = "Monitor Dashboard | " + this.stakeholder.name;
this.description = "Monitor Dashboard | " + this.stakeholder.name;
this.setMetadata();
if (this.hasPermission((this.view && this.isManager(this.stakeholder))?this.view:this.stakeholder.visibility)) {
this.setView(params);
} else {
this.privateStakeholder = true;
if (subscription) {
subscription.unsubscribe();
}
}));
}
if (this.isPublicOrIsMember(stakeholder.visibility)) {
//this.getDivContents();
// this.getPageContents();
this.status = this.errorCodes.DONE;
this.setView(params);
} else {
this.privateStakeholder = true;
// this.navigateToError();
if (subscription) {
subscription.unsubscribe();
}
}
}));
} else {
this.navigateToError();
if (subscription) {
@ -204,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);
}));
}
}));
}));
}
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.isViewPublic = (queryParams['view'] == 'public');
}
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 += 2;
}
for (let filter of this.filters) {
count += filter.countSelectedValues;
}
return count;
}
public get isSmallScreen() {
return this.layoutService.isSmallScreen;
}
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.isPublicOrIsMember(topic.visibility));
if (this.activeTopic) {
if (params['category']) {
this.activeCategory = this.activeTopic.categories.find(category =>
(category.alias === params['category']) && this.isPublicOrIsMember(category.visibility));
if (!this.activeCategory) {
this.navigateToError();
return;
}
} else {
this.activeCategory = this.activeTopic.categories.find(category => this.isPublicOrIsMember(category.visibility));
if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
this.isPublicOrIsMember(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.isPublicOrIsMember(subCategory.visibility)));
if (!this.activeSubCategory) {
this.navigateToError();
return;
}
} else {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
this.isPublicOrIsMember(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.isPublicOrIsMember(topic.visibility));
if (this.activeTopic) {
this.activeCategory = this.activeTopic.categories.find(category => this.isPublicOrIsMember(category.visibility));
if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.isPublicOrIsMember(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"]));
@ -425,166 +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 = "";
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.isPublicOrIsMember(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);
this.subscriptions.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(pair[0]), pair[1]).subscribe(response => {
indexes.forEach(([i, 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 isPublicOrIsMember(visibility: Visibility): boolean {
return !(visibility == "PRIVATE" || (this.isViewPublic && visibility != "PUBLIC"));
}
public countSubCategoriesToShow(category: Category): number {
return category.subCategories.filter(subCategory => this.isPublicOrIsMember(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.isPublicOrIsMember(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, j) {
event.stopPropagation();
this.showDescriptionOverlay[j] = !this.showDescriptionOverlay[j];
}
closeDescriptionOverlay(event: ClickEvent,j) {
if(event.clicked && this.showDescriptionOverlay[j]) {
this.showDescriptionOverlay[j] = 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,15 +23,21 @@ 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";
import {SliderUtilsModule} from "../openaireLibrary/sharedComponents/slider-utils/slider-utils.module";
import {
SidebarMobileToggleModule
} from "../openaireLibrary/dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, ErrorMessagesModule,
HelperModule, Schema2jsonldModule, SEOServiceModule, MonitorRoutingModule, SideBarModule, InputModule,
UserMiniModule, ClickModule, BottomModule, RangeFilterModule, SearchFilterModule, PageContentModule, IconsModule,
LogoUrlPipeModule
LogoUrlPipeModule, NumberRoundModule, SliderTabsModule, SliderUtilsModule, SidebarMobileToggleModule
],
declarations: [
MonitorComponent
@ -47,6 +53,6 @@ import {LogoUrlPipeModule} from "../openaireLibrary/utils/pipes/logoUrlPipe.modu
})
export class MonitorModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([incognito, filters, graph]);
this.iconsService.registerIcons([incognito, filters]);
}
}

@ -1 +1 @@
Subproject commit 770c3fb3eff99ddab059f0de657f576443b01a7d
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,12 +33,6 @@ export class MonitorPublicationComponent {
if (stakeholder) {
this.initialized = true;
this.communityId = stakeholder.alias;
this.subscriptions.push(this.configurationService.communityInformationState.subscribe(portal => {
if (portal) {
console.debug(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

@ -4,7 +4,7 @@ import {RouterModule} from "@angular/router";
@NgModule({
imports: [CommonModule, RouterModule.forChild([
// Search Pages
{ path: '', redirectTo: 'find/research-outcomes'},
{ path: '', redirectTo: 'find/research-outcomes', pathMatch: 'full'},
{ path: 'find/research-outcomes', loadChildren: () => import('./searchPages/simple/searchResearchResults.module').then(m => m.MonitorSearchResearchResultsModule)},
{ path: 'find/projects', loadChildren: () => import('./searchPages/simple/searchProjects.module').then(m => m.MonitorSearchProjectsModule)},
{ path: 'find/dataproviders', loadChildren: () => import('./searchPages/simple/searchDataProviders.module').then(m => m.MonitorSearchDataProvidersModule)},
@ -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,55 +0,0 @@
.uk-card {
min-height: 270px;
}
.number-preview {
border: 1px solid var(--muted-color);
background: transparent;
border-radius: 6px;
min-width: 100px;
min-height: 70px;
}
.refresh-indicator {
background-color: rgba(0, 0, 0, 0.50);
border-radius: 6px;
position: absolute;
color: var(--light-color);
z-index: 1;
}
.section {
padding: 60px 45px;
border-radius: 6px;
border: 1px solid var(--muted-color);
position: relative;
background: var(--light-color);
border-left: 5px var(--primary-color) solid;
}
.section .tools {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -100%);
width: 50px;
max-width: 50px;
padding: 5px 0 5px 10px;
background-image: var(--dashboard-primary-image);
color: var(--light-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;
}
.section:hover .tools {
display: block;
}
.section:hover .tools a {
color: currentColor;
}
.section:hover .tools a:hover {
text-decoration: none;
}

View File

@ -1,470 +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="actions 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 [attr.uk-tooltip]="(number.defaultId?'Default sections cannot be deleted':'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-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-card-body uk-flex uk-flex-column uk-flex-center 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);">
<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-center">
<h3 class="number uk-text-bold uk-text-background">
<span *ngIf="numberResults.get(i + '-' + j)">{{numberResults.get(i + '-' + j) | number}}</span>
<span *ngIf="!numberResults.get(i + '-' + j)">--</span>
</h3>
<div class="uk-text-uppercase uk-text-small uk-margin-top">
{{indicator.name ? indicator.name : 'No title available'}}
</div>
</div>
</div>
</div>
</ng-template>
</div>
<div *ngIf="isCurator" class="uk-margin-medium-top">
<div class="uk-grid" uk-grid>
<div [ngClass]="getNumberClassBySize('small')">
<a class="uk-card uk-card-default uk-card-body uk-link-reset" (click)="editNumberIndicatorOpen(number)">
<h6 class="uk-text-bold uk-text-center">
Create a number Indicator
</h6>
<div class="uk-flex uk-flex-center uk-text-background uk-margin-large-top">
<icon name="add" [flex]="true" ratio="3"></icon>
</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="actions 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 [title]="(chart.defaultId?'Default sections cannot be deleted':'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-column-medium" 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 uk-blend-multiply" [ngClass]="'uk-height-' + (indicator.height?indicator.height.toLowerCase():'medium')"></iframe>
<div *ngIf="properties.disableFrameLoad && 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[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-medium-top">
<div class="uk-grid uk-grid-column-medium" 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 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 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 enchancements 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'"
[src]="indicator.indicatorPaths[i].safeResourceUrl" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"
class="uk-width-1-1 uk-height-large uk-blend-multiply"></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">
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.
<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>
</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">
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?
</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>

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,246 +0,0 @@
<aside *ngIf="stakeholder" id="sidebar_main">
<div id="sidebar_content">
<div class="menu_section uk-margin-top">
<ul class="uk-list uk-nav uk-nav-default" uk-nav>
<li>
<a [routerLink]="'/admin/' + stakeholder.alias">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon class="menu-icon" name="west" [flex]="true"></icon>
</div>
<span class="uk-width-expand uk-text-truncate uk-margin-small-left" [class.uk-hidden]="!open">Indicators</span>
</div>
</a>
</li>
</ul>
</div>
<div class="menu_section uk-margin-large-top">
<ul class="uk-list uk-nav uk-nav-default" uk-nav>
<ng-template ngFor [ngForOf]="stakeholder.topics" let-topic let-i="index">
<li class="uk-visible-toggle" [class.uk-active]="topicIndex == i">
<a [routerLink]="'/admin/'+stakeholder.alias + '/indicators/' + topic.alias"
[title]="topic.name">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="topic.icon" class="uk-width-auto">
<icon class="menu-icon" [svg]="topic.icon" [flex]="true"></icon>
</div>
<span *ngIf="open || !topic.icon" [class.uk-text-small]="!open"
class="uk-width-expand uk-text-truncate uk-margin-small-left">
{{topic.name}}
</span>
<span *ngIf="open" class="uk-invisible-hover" [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">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editTopicOpen(i); hide(element)">Edit</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)="changeTopicStatus(i, 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="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)">Delete</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>
</div>
</a>
</li>
</ng-template>
<li *ngIf="isCurator">
<a (click)="editTopicOpen(-1); $event.preventDefault()">
<div class="uk-flex uk-flex-middle uk-flex-center">
<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" [class.uk-hidden]="!open">Create new topic</span>
</div>
</a>
</li>
</ul>
</div>
<div *ngIf="stakeholder.topics.length > 0" class="uk-position-bottom uk-margin-bottom">
<div class="uk-flex uk-flex-center">
<button class="uk-icon-button uk-button-primary" uk-tooltip="Preview">
<icon name="visibility" [flex]="true"></icon>
</button>
<div #element uk-dropdown="mode: click; pos: top-left; offset: 5; delay-hide: 0; flip: false"
class="uk-padding-remove-horizontal">
<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>
</div>
</div>
</aside>
<div *ngIf="stakeholder && filters" page-content (stickyEmitter)="stickyPageHeader = $event">
<div header>
<div *ngIf="stakeholder.topics.length > 0 && stakeholder.topics[topicIndex]">
<div class="uk-width-expand uk-flex uk-margin-top uk-flex-middle info" [class.uk-active]="stickyPageHeader">
<img [src]="stakeholder | logoUrl" class="uk-margin-right uk-blend-multiply">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">Admin Dashboard - Manage Indicators</div>
<h1 class="uk-h4 uk-margin-remove">{{stakeholder.name}}</h1>
</div>
</div>
<div class="uk-margin-top">
<ul *ngIf="stakeholder.topics[topicIndex]" class="uk-tab">
<ng-template ngFor [ngForOf]="stakeholder.topics[topicIndex].categories" let-category let-i="index">
<li class="uk-visible-toggle uk-flex" [class.uk-active]="categoryIndex === i">
<a (click)="chooseCategory(i)">
<span class="title"> {{category.name}}</span>
</a>
<span class="uk-invisible-hover uk-flex uk-flex-column uk-flex-center uk-margin-small-left" [class.uk-invisible-hover]="categoryIndex !== i"
(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">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editCategoryOpen(i); hide(element)">Edit</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)="changeCategoryStatus(i, 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="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(i, 'delete'); hide(element)">Delete</a></li>
</ng-container>
</ul>
</div>
</span>
</li>
</ng-template>
<li *ngIf="isCurator">
<a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Create new category</span>
</a>
</li>
</ul>
</div>
</div>
</div>
<div inner>
<ul *ngIf="stakeholder.topics.length > 0 && stakeholder.topics[topicIndex].categories.length > 0 && stakeholder.topics[topicIndex].categories[categoryIndex]"
class="uk-subnav uk-subnav-pill uk-margin-top">
<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">
<a (click)="chooseSubcategory(i);$event.preventDefault()" class="uk-margin-small-left">
<span>{{subCategory.name}}</span>
</a>
<span class="uk-invisible-hover uk-flex uk-flex-column uk-flex-center uk-margin-small-left" [class.uk-invisible-hover]="categoryIndex !== 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">
<ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator">
<li>
<a (click)="editSubCategoryOpen(i); hide(element)">Edit</a>
</li>
<li *ngIf="indicators"><a (click)=" indicators.exportIndicators();hide(element)">Export indicators</a></li>
<li *ngIf="indicators"><a (click)="file.value = ''; this.index=i; file.click(); hide(element)">Import indicators</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)="changeSubcategoryStatus(i, 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="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)">Delete</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-margin-small-left">Create new subcategory</span>
</a>
</li>
</ul>
<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">
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?
</modal-alert>
<modal-alert #editModal classTitle="uk-background-primary uk-light" (alertOutput)="saveElement()" [okDisabled]="form && (form.invalid || form.pristine)">
<div *ngIf="form" class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="form"
uk-grid>
<div input [formInput]="form.get('name')" placeholder="Title"></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 input [formInput]="form.get('visibility')" placeholder="Status" [options]="stakeholderUtils.visibility" type="select">
</div>
</div>
</modal-alert>

View File

@ -1,574 +0,0 @@
import {Component, OnDestroy, OnInit, ViewChild} 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 {Subject, Subscriber, Subscription} from "rxjs";
import {FormBuilder, FormGroup, 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";
declare var UIkit;
@Component({
selector: 'topic',
templateUrl: './topic.component.html',
})
export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
private subscriptions: any[] = [];
private paramsSub: any;
public properties: EnvProperties = properties;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public loading: boolean = true;
public stickyPageHeader: boolean = false;
public stakeholder: Stakeholder;
public user: User;
/**
* Stakeholder change event
* */
public change: Subject<void> = new Subject<void>();
/**
* Current topic
**/
public topicIndex: number = 0;
/**
* Current category
*/
public categoryIndex: number = 0;
/**
* Current Subcategory
*/
public subCategoryIndex: number = 0;
/**
* Current element and index of topic, category or subcategory to be deleted.
*/
public form: FormGroup;
public element: Topic | Category | SubCategory;
public type: 'topic' | 'category' | 'subcategory' = "topic";
public index: number = -1;
@ViewChild('deleteModal', {static: true}) deleteModal: AlertModal;
@ViewChild('editModal', {static: true}) editModal: AlertModal;
public elementChildrenActionOnDelete: string;
public filters: FormGroup;
public all: Option = {
value: 'all',
label: 'All'
};
constructor(
private route: ActivatedRoute,
private router: Router,
private title: Title,
private fb: FormBuilder,
private stakeholderService: StakeholderService,
private userManagementService: UserManagementService,
private layoutService: LayoutService) {
}
public ngOnInit() {
let subscription: Subscription;
this.paramsSub = this.route.params.subscribe(params => {
if (subscription) {
subscription.unsubscribe();
}
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = stakeholder;
if (params['topic']) {
this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
} else {
this.topicIndex = 0;
}
this.categoryIndex = 0;
this.subCategoryIndex = 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.subscriptions.push(subscription);
});
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}))
}
public ngOnDestroy() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
if (this.paramsSub instanceof Subscriber) {
this.paramsSub.unsubscribe();
}
}
canExit(): boolean {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
this.stakeholderService.setStakeholder(this.stakeholder);
return true;
}
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 closeDeleteModal() {
// this.deleteModal.cancel();
// }
public deleteElement() {
if (this.type === "topic") {
this.deleteTopic();
} else if (this.type === "category") {
this.deleteCategory();
} else {
this.deleteSubcategory();
}
}
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.subscriptions.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 => {
if (this.index === -1) {
this.stakeholder.topics.push(topic);
} else {
this.stakeholder.topics[this.index] = HelperFunctions.copy(topic);
}
};
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(index: number, visibility: Visibility) {
this.type = 'topic';
let path = [
this.stakeholder._id,
this.stakeholder.topics[index]._id
];
this.changeStatus(this.stakeholder.topics[index], path, visibility);
}
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.topicIndex = Math.max(0, this.index - 1);
this.stakeholder.topics.splice(this.index, 1);
};
this.delete('Topic has been successfully be deleted', path, callback, (this.topicIndex === this.index));
}
public chooseCategory(index: number) {
this.categoryIndex = index;
this.subCategoryIndex = 0;
}
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.subscriptions.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 => {
if (this.index === -1) {
this.stakeholder.topics[this.topicIndex].categories.push(category);
} else {
this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category);
}
};
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(index: number, visibility: Visibility) {
this.index = index;
this.type = 'category';
let path = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
];
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.index], path, visibility);
}
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.categoryIndex = Math.max(0, this.index - 1);
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
};
this.delete('Category has been successfully be deleted', path, callback);
}
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.subscriptions.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 => {
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);
}
};
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(index: number, visibility: Visibility) {
this.index = index;
this.type = 'subcategory';
let path = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id
];
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index], path, visibility);
}
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.subCategoryIndex = Math.max(0, this.index - 1);
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1);
};
this.delete('Subcategory has been successfully be deleted', path, callback);
}
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.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.open();
}
private save(message: string, path: string[], saveElement: any, callback: Function, redirect = false) {
this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
callback(saveElement);
this.stakeholderChanged();
UIkit.notification(message, {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
if (redirect) {
this.router.navigate(['../' + saveElement.alias], {
relativeTo: this.route
});
}
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
}));
}
private delete(message: string, path: string[], callback: Function, redirect = false) {
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => {
callback();
this.stakeholderChanged();
UIkit.notification(message, {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
if (redirect) {
this.back();
}
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
}));
}
private changeStatus(element: Topic | Category | SubCategory, path: string[], visibility: Visibility) {
this.subscriptions.push(this.stakeholderService.changeVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => {
element.visibility = visibility;
UIkit.notification(StringUtils.capitalize(this.type) + ' has been <b>successfully changed</b> to ' + element.visibility.toLowerCase(), {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
}));
}
back() {
this.router.navigate(['../'], {
relativeTo: this.route
});
}
chooseSubcategory(subcategoryIndex: number) {
this.subCategoryIndex = subcategoryIndex;
}
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);
}
}

View File

@ -1,43 +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";
@NgModule({
imports: [
CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule,
ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule
],
declarations: [
TopicComponent, IndicatorsComponent
],
providers: [
PreviousRouteRecorder,
PiwikService
],
exports: [
TopicComponent
]
})
export class TopicModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([earth, incognito, restricted]);
}
}

View File

@ -3,23 +3,11 @@
<loading></loading>
</div>
</div>
<ng-template #tabs>
<div class="uk-margin uk-margin-remove-bottom">
<ul class="uk-tab">
<li [class.uk-active]="tab === 'manager'"><a routerLink="../manager">Managers</a></li>
<li [class.uk-active]="tab === 'member'"><a routerLink="../member">Members</a></li>
</ul>
</div>
</ng-template>
<role-users *ngIf="!loading && stakeholder" [id]="stakeholder.alias" [type]="stakeholder.type" [name]="stakeholder.name" [link]="link" [role]="tab" [message]="messages.get(tab)"
[emailComposer]="emailComposer" [notificationFn]="notificationFn" (stickyEmitter)="stickyPageHeader = $event">
<div class="uk-flex uk-flex-middle uk-margin-top info" [class.uk-active]="stickyPageHeader">
<img [src]="stakeholder | logoUrl" class="uk-margin-right uk-blend-multiply">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">Admin Dashboard - Manage {{users}}</div>
<h1 class="uk-h4 uk-margin-remove">{{stakeholder.name}}</h1>
</div>
</div>
<ng-container [ngTemplateOutlet]="tabs"></ng-container>
[emailComposer]="emailComposer" [notificationFn]="notificationFn">
<ul class="uk-tab uk-margin-remove-bottom uk-margin-medium-top">
<li [class.uk-active]="tab === 'manager'"><a routerLink="../manager">Managers</a></li>
<li [class.uk-active]="tab === 'member'"><a routerLink="../member">Members</a></li>
</ul>
</role-users>

View File

@ -46,7 +46,6 @@ export class UsersComponent implements OnInit {
notification.groups = [recipient];
return notification;
}
public stickyPageHeader: boolean = false;
constructor(private stakeholderService: StakeholderService,
private userManagementService: UserManagementService,

View File

@ -1,47 +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";
@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 {
return zip(
this.userManagementService.getUserInfo(false)
,this.stakeholderService.getStakeholder(alias)
).pipe(take(1),map(res =>
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': LoginErrorCodes.NOT_ADMIN, '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,950 +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 (endYear && key == "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 (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)]) {
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"] = [];
}
let field = queries["query"]["select"][0]["field"];
let filterString = IndicatorFilterUtils.getFilter(field&&field.length > 0? field.split(".")[0]:"",filterType);
if(filterString){
let filter = JSON.parse(filterString);
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"]) {
if (gfilter["field"].indexOf(" funder") != -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 d577c6d69a55901e319cf0cf5b93f900f1cdeaab
Subproject commit 186e4bf732f96459a1e22b44ba172f08f0c11d48

@ -1 +0,0 @@
Subproject commit 141c71c3104bab1382e6008697043ea87e03ea44

View File

@ -1,15 +1,22 @@
.stakeholderPage {
.monitor {
/* Import OpenAIRE theme*/
@import (multiple) "~src/assets/openaire-theme/less/_import";
@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;
/** Global */
@global-primary-gradient: linear-gradient(110deg, @monitor-light-color 0%, @monitor-dark-color 100%);
/** Background*/
/** Background */
@background-primary-background: @monitor-color;
@background-primary-background-gradient: none;
/** Buttons */
/** Button */
@button-primary-background: @monitor-color;
@button-secondary-border: @monitor-color;
@button-secondary-color: @monitor-color;
@ -26,19 +33,59 @@
@list-primary-color: @monitor-color;
/* Navbar */
@inverse-navbar-background: @monitor-color;
@inverse-navbar-background-image: url("banner.jpg");
/** Text */
@text-primary-color: @monitor-color;
@text-background-color: @monitor-color;
@inverse-text-primary-color: @monitor-color;
/* Slider */
@dotnav-item-background: fade(@monitor-color, 50%);
@dotnav-item-hover-background: @monitor-color;
@dotnav-item-onclick-background: @monitor-color;
@dotnav-item-active-background: @monitor-color;
/* General */
@general-search-form-background: @monitor-dashboard-background;
@general-tab-featured-tab: @monitor-color;
/* Landing */
@landing-portal-color: @monitor-color;
/* Dashboard */
@dashboard-page-content-background: @monitor-dashboard-background;
@dashboard-primary-background: @monitor-color;
@dashboard-menu-section-sublist-border: fade(@monitor-color, 30%);
& #filters_icon .start {
stop-color: @monitor-light-color;
}
& #filters_icon .end {
& #filters_icon .end {
stop-color: @monitor-dark-color;
}
.private-data {
background-image: url("private-overlay.png");
background-repeat: no-repeat;
background-size: cover;
min-height: 100vh;
}
.preview {
position: fixed;
bottom: 40px;
left: 50%;
transform: translateX(-50%);
background: @global-inverse-color;
border: 2px solid @background-primary-background;
border-radius: @global-border-radius;
box-shadow: @global-large-box-shadow;
padding: 20px 25px;
z-index: @global-z-index;
}
}
#print_toggle {
@ -49,6 +96,13 @@
top: 400px !important;
}
@media (max-width: @breakpoint-small-max) {
#filters_switcher_toggle {
top: unset !important;
bottom: 10vh;
}
}
/* Quick fix for svgs with a class that makes their opacity: 0.5*/
svg .a {
opacity: 1 !important;

@ -1 +1 @@
Subproject commit a61c749816accd456cf30c9e4983d61282f28a89
Subproject commit e721fef20399f15c9dc9bee28b3d7e9b92db2021

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

View File

@ -1,717 +0,0 @@
{
"stakeholders": [
{
"id": "1",
"type": "funder",
"index_id": "EC",
"index_name": "European Comission",
"index_shortName": "EC",
"alias": "EC",
"isDefaultProfile": false,
"isActive": true,
"isPublic": true,
"creationDate": "08-10-2019",
"updateDate": "08-10-2019",
"managers": null,
"topics": [
{
"name": "OpenScience",
"alias": "openScience",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isActive": true,
"isPublic": true,
"categories": [
{
"name": "Overview",
"alias": "overview",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": true,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"embargo"
]
}
]
}
],
"charts": [
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
},
{
"name": "Open",
"description": "open",
"alias": "open",
"isActive": true,
"isPublic": true,
"numbers": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"embargo"
]
}
]
}
],
"charts": [
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
}
]
},
{
"name": "Publications",
"alias": "publications",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": false,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"embargo"
]
}
]
}
],
"charts": [
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
}
]
},
{
"name": "Research data",
"alias": "researchData",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": false,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
],
"charts": [
]
}
]
},
{
"name": "Software",
"alias": "software",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": false,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
],
"charts": [
]
}
]
},
{
"name": "Other",
"alias": "other",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": false,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
],
"charts": [
]
}
]
}
]
},
{
"name": "Collaboration",
"alias": "collaboration",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isActive": true,
"isPublic": true,
"categories": [
{
"name": "Overview",
"alias": "overview",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": true,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"embargo"
]
}
]
}
],
"charts": [
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
}
]
}
]
},
{
"name": "Impact/Correlation",
"alias": "impact-correlation",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isActive": true,
"isPublic": true,
"categories": [
{
"name": "Overview",
"alias": "overview",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do...",
"isOverview": true,
"isActive": true,
"isPublic": true,
"subCategories": [
{
"name": null,
"description": null,
"alias": null,
"isActive": true,
"isPublic": true,
"numbers": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/{index_shortName}",
"jsonPath": [
"statistics",
"embargo"
]
}
]
}
],
"charts": [
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
}
]
}
]
}
]
}
],
"indicators": [
{
"id": "1",
"type": "number",
"name": "Total",
"description": "Total number of publications",
"tags": [
"publications"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"publications"
]
}
]
},
{
"id": "2",
"type": "number",
"name": "Open",
"description": "Total number of open access publications",
"tags": [
"publication",
"open access"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"open_access"
]
}
]
},
{
"id": "3",
"type": "number",
"name": "Embargo",
"description": "Total number of embargoed publications",
"tags": [
"publication",
"embargo"
],
"width": "small",
"indicatorPaths": [
{
"type": "",
"url": "/funders/ec",
"jsonPath": [
"statistics",
"embargo"
]
}
]
},
{
"id": "4",
"type": "charts",
"name": "Number of publications by project",
"description": "Number of publications by project",
"tags": [
"publication",
"project"
],
"width": "large",
"indicatorPaths": [
{
"type": "bar graph",
"url": "https://www.openaire.eu/stats/chart.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22column%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22EC%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
},
{
"type": "table",
"url": "https://www.openaire.eu/stats/gtable.php?com=query&data={%22table%22:%22result%22,%22fields%22:[{%22fld%22:%22number%22,%22agg%22:%22count%22,%22type%22:%22pie%22,%22yaxis%22:1,%22c%22:false}],%22xaxis%22:{%22name%22:%22result_projects-project-title%22,%22agg%22:%22avg%22},%22group%22:%22%22,%22color%22:%22%22,%22type%22:%22chart%22,%22size%22:%2230%22,%22sort%22:%22count-number%22,%22yaxisheaders%22:[%22%22],%22fieldsheaders%22:[%22publications%22],%22in%22:[],%22filters%22:[{%22name%22:%22result_projects-project-funder%22,%22values%22:[%22European%20Commission%22],%22to%22:%22-1%22},{%22name%22:%22type%22,%22values%22:[%22publication%22],%22to%22:%22-1%22}],%22having%22:[],%22xStyle%22:{%22r%22:-90,%22s%22:%22-%22,%22l%22:%22-%22,%22ft%22:10,%22wt%22:%22-%22},%22title%22:%22European%20Commission%20Publications%20by%20project%20(top%2030)%22,%22subtitle%22:%22%22,%22xaxistitle%22:%22project%22,%22order%22:%22d%22}",
"jsonPath": []
}
]
}
]
}

View File

@ -1,29 +0,0 @@
@import "assets/openaire-theme/css/structure/variables.css";
@import "assets/openaire-theme/css/openaire.css";
@import "assets/common-assets/library.css";
@import "assets/dashboard-theme/main.css";
.stakeholderPage {
/* Structure */
--structure-page-content-background-color: #F3F3F3;
--structure-page-content-background-color-rgb: 243, 243, 243;
/* Login */
--login-background-color: var(--light-color);
--login-background-color-hover: var(--light-color);
--login-color: var(--primary-color);
--login-color-hover: var(--secondary-color);
/* Dashboard */
--dashboard-primary-color: var(--monitor-color);
--dashboard-primary-color-rgb: var(--monitor-color-rgb);
--dashboard-primary-image: linear-gradient(110deg, var(--monitor-light-color) 0%, var(--monitor-dark-color) 100%);
--dashboard-primary-inverse-color: var(--light-color);
/* Search */
--search-form-background: var(--structure-page-content-background-color);
}
.stakeholderPage .landing {
--landing-text-primary-color: var(--monitor-color);
}

View File

@ -1,125 +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://dx.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",
searchLinkToEntityRegistriesDataProvidersTable: "/search/entity-registries-table",
searchLinkToJournals: "/search/journals",
searchLinkToJournalsTable: "/search/journals-table",
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,123 +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://dx.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",
searchLinkToEntityRegistriesDataProvidersTable: "/search/entity-registries-table",
searchLinkToJournals: "/search/journals",
searchLinkToJournalsTable: "/search/journals-table",
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,114 +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://dx.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:8080/login-service/openid_connect_login",
userInfoUrl: "http://mpagasas.di.uoa.gr:8080/login-service/userInfo",
logoutUrl: "http://mpagasas.di.uoa.gr:8080/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:8080/uoa-monitor-service",
adminToolsAPIURL: "http://duffy.di.uoa.gr:8080/uoa-monitor-service/",
notificationsAPIURL: "http://duffy.di.uoa.gr:8080/uoa-monitor-service/notification/",
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",
searchLinkToEntityRegistriesDataProvidersTable: "/search/entity-registries-table",
searchLinkToJournals: "/search/journals",
searchLinkToJournalsTable: "/search/journals-table",
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, renderModuleFactory } from '@angular/platform-server';

View File

@ -22,16 +22,6 @@ import '@angular/localize/init';
* BROWSER POLYFILLS
*/
/** IE10 and IE11 requires the following for NgClass support on SVG elements */
// import 'classlist.js'; // Run `npm install --save classlist.js`.
/**
* Web Animations `@angular/platform-browser/animations`
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
*/
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
/**
* By default, zone.js will patch all possible macroTask and DomEvents
* user can disable parts of macroTask/DomEvents patch by setting following flags
@ -59,7 +49,7 @@ import '@angular/localize/init';
/***************************************************************************************************
* Zone JS is required by default for Angular itself.
*/
import 'zone.js/dist/zone'; // Included with Angular CLI.
import 'zone.js'; // Included with Angular CLI.
/***************************************************************************************************

View File

@ -2,5 +2,10 @@
/* Import OpenAIRE theme*/
@import "~src/assets/openaire-theme/less/_import";
@import "assets/monitor-dashboard-custom";
@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

@ -1,20 +1,16 @@
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
platformBrowserDynamicTesting(), {
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

@ -8,16 +8,16 @@
"declaration": false,
"module": "es2020",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"target": "ES2022",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
],
"useDefineForClassFields": false
}
}