Compare commits

...

104 Commits

Author SHA1 Message Date
argirok a3d67696ad commit libraries 2 months ago
argirok d2384ea07f Merge branch 'develop' 2 months ago
argirok c1e306cff0 [develop | DONE | ADDED ] add again publicationyear in criteria fields, add different list of verbs for numeric values 2 months ago
argirok f2e2edd1f2 [develop | DONE | FIXED ] community status checks 2 months ago
argirok 1003382304 [develop | DONE | REMOVED] : criteria-utils: comment out publicationyear option until integer value operators are available 3 months ago
argirok 4147ffca98 Merge remote-tracking branch 'origin/develop' into develop 5 months ago
argirok f23f75e2d8 [develop | DONE | UPDATED] Community form: remove old visibility statuses 5 months ago
argirok b5c60f85e9 Merge branch 'develop' 6 months ago
argirok a767a1d890 commit libraries 6 months ago
Alex Martzios 7827d23088 [develop | DONE | ADDED] add two new fields in datasources selection criteria & advanced criteria 6 months ago
Konstantinos Triantafyllou b4f01d1fd0 [develop | DONE]: Remove overflow auto from menu_section in customization 6 months ago
Konstantinos Triantafyllou bc201a1ae8 [develop | DONE | FIXED]: Fix sidebar in customization page. 6 months ago
argirok 66a0b038b6 Merge remote-tracking branch 'origin/develop' into develop
# Conflicts:
#	src/environments/environment.beta.ts
#	src/environments/environment.prod.ts
#	src/environments/environment.ts
6 months ago
argirok 2d6b144441 [develop | DONE | UPDATED] properties: use library properties 6 months ago
argirok a02dbded6e [develop | WIP] : properties: add comments what to check 6 months ago
argirok 1b23a25e24 [develop | DONE | UPDATED] :users-managers component add missing attribute to composer function 6 months ago
Konstantinos Triantafyllou e6a5dbc2b4 Merge pull request 'angular-16' (#6) from angular-16 into develop
Reviewed-on: #6
6 months ago
Konstantinos Triantafyllou 24ed9f0690 [angular-16 | FIXED]: Fix width of main content 6 months ago
Konstantinos Triantafyllou 47567e484b Merge pull request '[angular-16-community-projects-availableSince | DONE | UPDATE] : show project link only when it is available before the db update date' (#5) from angular-16-community-projects-availableSince into angular-16
Reviewed-on: #5
6 months ago
Konstantinos Triantafyllou 8f03223bcc Merge pull request '[angular-16-update-zenodo-api | DONE | UPDATE] : update zenodo community API - update method signatures' (#4) from angular-16-update-zenodo-api into angular-16
Reviewed-on: #4
6 months ago
argirok 1c8e46df21 [angular-16-community-projects-availableSince | DONE | UPDATE] : show project link only when it is available before the db update date 6 months ago
Konstantinos Triantafyllou 4ce3080146 [angular-16 | DONE | CHANGED]: Make dashboard-sidebar sticky instead of fixed. 6 months ago
argirok ba9f7db240 [angular-16-update-zenodo-api | DONE | UPDATE] : update zenodo community API - update method signatures 6 months ago
argirok 1907f6f723 beta properties: use new claims service 6 months ago
Konstantinos Triantafyllou 6546fd40a1 Merge from develop 7 months ago
Konstantinos Triantafyllou e2122bd14e Update libraries 7 months ago
Konstantinos Triantafyllou 8e27e29605 Enable membership and add condition in users->members 7 months ago
Konstantinos Triantafyllou e5a4472c6d Edit community fix margin in logo section 7 months ago
Konstantinos Triantafyllou 0ffc63ba95 Merge develop into angular-16 7 months ago
argirok 3c46fb9459 Merge branch 'master' of code-repo.d4science.org:MaDgIK/connect-admin 7 months ago
argirok 63521a83aa commit libraries 7 months ago
argirok 2f9b12c478 Merge branch 'new-community-api' into develop 7 months ago
argirok 0ef15e01cf commit libraries 7 months ago
Konstantina Galouni 5a4e76b0c2 Connect | develop: environments/: Added property swhURL 7 months ago
Konstantinos Triantafyllou 4076f96fb1 Update libraries 7 months ago
argirok 0b703bceec Community projects: add filtering and sorting 7 months ago
argirok b54fa1eaf9 update labels for claimOptions field 7 months ago
argirok 205db8bf10 limit the requests for add projetcs 7 months ago
argirok 78dcc5a208 Merge branch 'develop' into new-community-api 7 months ago
argirok ab85ca7e3c Commit library changes 7 months ago
argirok 7bcab90231 update manage projects page to use paging and search through new communities API 7 months ago
Konstantinos Triantafyllou ef19492aad Remove types/node from package.json 8 months ago
argirok 4dbf21ba48 update remove method on the screen you search and add projects and communities 8 months ago
argirok 7568c668b7 hide membership in edit form until the functionality is ready 8 months ago
Konstantinos Triantafyllou 4365aab4bb Merge from Develop. Resolve (Connect Admin release 30th August 2023 #3) 8 months ago
Konstantinos Triantafyllou 09c04d02b1 Merge from develop 8 months ago
Konstantinos Triantafyllou 93efde0b07 Fix criteria disabled condition because of null in selectionCriteria. 8 months ago
Konstantinos Triantafyllou df4b9be6fc Update uikit to version 3.16.24 8 months ago
Konstantinos Triantafyllou f8a7d0619e Update color picker and fix css of mining 9 months ago
Konstantinos Triantafyllou 2791c7c26b Add mining and update to angular-16 9 months ago
Konstantinos Triantafyllou 2943b496ee Update material to angular 16. 9 months ago
Konstantinos Triantafyllou 247452b860 Update angular to angular 16. 9 months ago
Konstantinos Triantafyllou f11b014248 Update Zone to 0.13.1 9 months ago
Konstantinos Triantafyllou 0dd4fc6717 Update material to angular 15. 9 months ago
Konstantinos Triantafyllou a97bac9e69 Migrate angular core and cli to version 15 and update dependencies to be compatible with the newer version. 9 months ago
Konstantinos Triantafyllou 353fe17126 Update typescript to version 4.9.5 and remove mining until migration ends 9 months ago
Konstantinos Triantafyllou fb6f423273 Update libraries 9 months ago
argirok f63cd1ec60 add fields claim and membership in edit form 9 months ago
argirok d9b0365a1d clean up imports for deleted SearchZenodoCommunitiesService 10 months ago
argirok 3a4203aef8 Merge branch 'develop' into new-community-api 10 months ago
Konstantinos Triantafyllou a79fd13a17 Update piwik with the new methods 10 months ago
argirok 662b514ab5 apply initial changes base odn new community API 10 months ago
Konstantinos Triantafyllou 500dd61f9b Update library. Fix an expression error in advanced-criteria. Add message if there are no subjects in each category. 10 months ago
Konstantinos Triantafyllou 94fc9bda53 Update libraries 10 months ago
Konstantina Galouni 82eec379f2 Updating libraries before prod release 10 months ago
Konstantina Galouni fa6f55e772 Updating openaireLibrary and openaire-theme before beta & prod release 10 months ago
Konstantinos Triantafyllou 946c4f62c4 Update library before release 10 months ago
Konstantinos Triantafyllou 58688d67de Merge pull request 'Connect-Admin release 19th June 2023' (#2) from develop into master
Reviewed-on: #2
10 months ago
argirok 1320fb7a75 Customization configuration: add fontsDarkMode attribute for hero section 11 months ago
argirok b0b277278e fix issue with datasource criteria form #8790 11 months ago
Konstantina Galouni 41d7882e61 Merge remote-tracking branch 'origin/develop' 11 months ago
Konstantina Galouni 6c10e2f397 Updating openaireLibrary before release 11 months ago
Konstantina Galouni 2c9e3e304d [Connect Admin | develop]: connect-admin-customization.component.ts: [Bug fix] Set savingChanges to false when all css are updated and set it to true when purging caches. 11 months ago
Konstantina Galouni 698174e302 [Connect Admin | develop]: app.component.ts: Added in menu "Fields of Science" and "Sustainable Development Goals". 11 months ago
Konstantinos Triantafyllou f98a3e9550 Resolved Connect-Admin release 25th May 2023 #1 11 months ago
Konstantinos Triantafyllou 854656f2ed Merge branch 'develop' of code-repo.d4science.org:MaDgIK/connect-admin into develop 11 months ago
Konstantinos Triantafyllou 508b8120b8 Update library, assets and theme. 11 months ago
Konstantina Galouni 3b6bebc2f1 Updating libraries before beta & prod release 11 months ago
Konstantinos Triantafyllou 07ef246d73 Add icons in manage-communities module. Update library and openaire-theme 12 months ago
Konstantinos Triantafyllou 3b4ea6102c Add message for file size limit in background-upload. 1 year ago
Konstantinos Triantafyllou ced4fe404d Fix margins in subjects 1 year ago
Konstantinos Triantafyllou ffa7ab71a0 Update Uikit to version 3.13.10. Update library 1 year ago
Konstantina Galouni 8712f6cae5 Updating openaireLibrary before beta release 1 year ago
Konstantina Galouni 871523cbbb [Connect Admin | develop]: community.service.ts: Renamed "advancedConstraint" to "advancedConstraints" (coming from community API). 1 year ago
Konstantinos Triantafyllou c174ad17c5 Update uikit to version 3.13.0 1 year ago
Konstantinos Triantafyllou 5123efc8c4 Update libraries before production deployment 1 year ago
Konstantinos Triantafyllou f4b54fa745 Update UIkit to 3.12.2. Add Subjects: Cliking add will add the input value also. 1 year ago
Konstantina Galouni 3f4a4b3501 Updating openaireLibrary - before BETA deploy 1 year ago
Konstantinos Triantafyllou f50525bcef Update libraries 1 year ago
Alex Martzios a3563ad1ef fix wrong condition statement for edit modal 1 year ago
Alex Martzios 070f9d369d add new feature: selection criteria by FoS and SDGs 1 year ago
Alex Martzios 88be699fd2 subjects page: 'enter key' now adds subjects in the list, number of selected SDGs and FoS changes dynamically, 'save' button is enabled/disabled based on overall changes, update submodules 1 year ago
Konstantinos Triantafyllou f2bbf0fb85 Delete header from all pages of communityInfo and users. Add advanced criteria page. 1 year ago
Alex Martzios a83852cffd WIP - add sdg/fos as subjects for community admin dashboards 1 year ago
Konstantinos Triantafyllou d9b4be9a5c Criteria: Change criteria in order to be a generic component. 1 year ago
Konstantinos Triantafyllou 798746e041 Update libraries before make new branches 1 year ago
Konstantinos Triantafyllou 400c0d8dce Remove offcanvas flip from navbar inputs. 1 year ago
Konstantinos Triantafyllou 39aad35c47 Move community info options to sidebar and delete internal tabs 1 year ago
Konstantinos Triantafyllou 83acc14d3b 1. Update library and assets. 2. Add deleteAthorizationLevel for managers with value manager. 1 year ago
Konstantina Galouni f2362b05cd [Connect Admin]: app.component.ts: [Bug fix] Error fixed in Deposit link in menu. 1 year ago
Konstantina Galouni 3ab4651ccd [Connect Admin]:personal-info.component.ts: Updated message of visibility | Changed visible default value to false (invisible). 1 year ago
Konstantina Galouni 6bbeff9152 [Connect Admin | Trunk & Library | angular-14]: Allow curators with profile to be invisible in the Gateway | Dynamically align custom menu.
1. CuratorInfo.ts: In Curator class added visible: boolean = true;
2. personal-info.module.ts: Imported MatSlideToggleModule.
3. personal-info.component.ts: Added slider to set curator profile to visible or invisible (default to visible).
4. menu.ts: In Menu class added field "featuredAlignment: MenuAlignment;" | Added enum MenuAlignment.
5. menu.component: Updated title "Menu settings" | Added "Menu Alignment" setting, to set if custom menu will be left, center or right alligned | Added notification when menu visibility changes.
6. help-content.service.ts: Added "alignMenu()" method to align custom menu dynamically.
1 year ago
Konstantina Galouni 4cfc90e7f8 [Connect Admin | Trunk]: In customization deleted icon "reset" icon replaced by "settings_backup_restore".
1. border.component.ts & customization.component.html & customization.module.ts & customize-buttons.component.ts: [Bug fix] Removed deprecated deleted icons | "reset" icon replaced by "settings_backup_restore" | removed padding from tooltips.
2. environment.ts: Commented properties "deleteCacheUrl" and "deleteBrowserCacheUrl".
1 year ago
Konstantina Galouni 9507545fd8 [Library | angular-14]: menu.component: Added commented code for creating new gateway specific pages when editing custom menu. 1 year ago

@ -1,7 +1,7 @@
rm -f interactiveminingv3.tgz
git clone https://code-repo.d4science.org/MaDgIK/interactive-mining.git
cd interactive-mining/
git checkout angular-14
git checkout angular-16
cd interactive-mining-angular-frontend/
npm install
npm run packagr

@ -17,41 +17,40 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^14.2.3",
"@angular/cdk": "^14.2.2",
"@angular/common": "^14.2.3",
"@angular/compiler": "^14.2.3",
"@angular/core": "^14.2.3",
"@angular/forms": "^14.2.3",
"@angular/localize": "^14.2.3",
"@angular/material": "^14.2.2",
"@angular/platform-browser": "^14.2.3",
"@angular/platform-browser-dynamic": "^14.2.3",
"@angular/router": "^14.2.3",
"@angular/animations": "^16.1.8",
"@angular/cdk": "^16.1.7",
"@angular/common": "^16.1.8",
"@angular/compiler": "^16.1.8",
"@angular/core": "^16.1.8",
"@angular/forms": "^16.1.8",
"@angular/localize": "^16.1.8",
"@angular/material": "^16.1.7",
"@angular/platform-browser": "^16.1.8",
"@angular/platform-browser-dynamic": "^16.1.8",
"@angular/router": "^16.1.8",
"clipboard": "^1.5.16",
"core-js": "^2.5.4",
"express": "^4.15.2",
"jquery": "^3.4.1",
"ng-recaptcha": "^10.0.0",
"ng-recaptcha": "^12.0.2",
"ng2-ckeditor": "1.3.7",
"ngx-color-picker": "^8.1.0",
"ngx-color-picker": "^14.0.0",
"rxjs": "^6.5.1",
"sass-loader": "7.3.1",
"ts-md5": "^1.2.0",
"tslib": "^2.0.0",
"uikit": "3.12.0",
"zone.js": "~0.11.4"
"uikit": "3.16.24",
"zone.js": "~0.13.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^14.2.3",
"@angular/cli": "^14.2.3",
"@angular/compiler-cli": "^14.2.3",
"@angular/language-service": "^14.2.3",
"@angular-devkit/build-angular": "^16.1.7",
"@angular/cli": "^16.1.7",
"@angular/compiler-cli": "^16.1.8",
"@angular/language-service": "^16.1.8",
"@types/ckeditor": "^4.9.10",
"@types/express": "^4.17.0",
"@types/jasmine": "~3.6.0",
"@types/jasminewd2": "~2.0.3",
"@types/node": "^12.11.1",
"@types/ckeditor": "^4.9.10",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.8.0",
"jasmine-spec-reporter": "~5.0.0",
@ -62,6 +61,6 @@
"karma-jasmine-html-reporter": "^1.6.0",
"protractor": "~7.0.0",
"ts-node": "~7.0.0",
"typescript": "~4.6.4"
"typescript": "~4.9.5"
}
}
}

@ -2,16 +2,15 @@
<loading [full]="true"></loading>
</div>
<div *ngIf="loading == false">
<div class="sidebar_main_swipe" [class.sidebar_main_active]="open && hasSidebar" [class.sidebar_mini]="!open && hasSidebar">
<div id="modal-container"></div>
<navbar *ngIf="hasHeader" portal="connect-admin" [header]="menuHeader" [communityId]="community ? community.communityId : null"
[userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user" [offCanvasFlip]="true"></navbar>
<div>
<dashboard-sidebar *ngIf="hasSidebar" [items]="sideBarItems" [specialMenuItem]="specialSideBarMenuItem"></dashboard-sidebar>
<main>
<div id="modal-container"></div>
<navbar *ngIf="hasHeader" portal="connect-admin" [header]="menuHeader" [communityId]="community ? community.communityId : null"
[userMenuItems]=userMenuItems [menuItems]="menuItems" [user]="user"></navbar>
<div class="sidebar_main_swipe uk-flex" [class.sidebar_main_active]="open && (hasSidebar || hasInternalSidebar)" [class.sidebar_mini]="!open && (hasSidebar || hasInternalSidebar)"
[class.sidebar_hover]="hover">
<dashboard-sidebar *ngIf="hasSidebar && !hasInternalSidebar" [items]="sideBarItems" [backItem]="backItem"></dashboard-sidebar>
<main class="uk-width-1-1">
<router-outlet></router-outlet>
</main>
</div>
</div>
</div>

@ -28,11 +28,12 @@ export class AppComponent implements OnInit {
params: BehaviorSubject<Params> = new BehaviorSubject<Params>(null);
data: BehaviorSubject<Data> = new BehaviorSubject<Data>(null);
hasSidebar: boolean = false;
hasInternalSidebar: boolean = false;
hasHeader: boolean = true;
hasAdminMenu: boolean = false;
isFrontPage: boolean = false;
sideBarItems: MenuItem[] = [];
specialSideBarMenuItem: MenuItem = null;
backItem: MenuItem = null;
menuItems: MenuItem[] = [];
menuHeader: Header = {
route: "/",
@ -81,6 +82,10 @@ export class AppComponent implements OnInit {
this.hasSidebar = hasSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasInternalSidebar.subscribe(hasInternalSidebar => {
this.hasInternalSidebar = hasInternalSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasHeader.subscribe(hasHeader => {
this.hasHeader = hasHeader;
this.cdr.detectChanges();
@ -126,7 +131,7 @@ export class AppComponent implements OnInit {
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 => {
@ -172,13 +177,17 @@ export class AppComponent implements OnInit {
} else {
ConnectHelper.setPortalTypeFromPid(id);
}
this.configurationService.initCommunityInformation(this.properties, this.properties.adminToolsCommunity);
this.configurationService.initPortal(this.properties, this.properties.adminToolsCommunity);
}
public get open() {
return this.layoutService.open;
}
public get hover() {
return this.layoutService.hover;
}
private buildMenu() {
this.userMenuItems = [];
this.sideBarItems = [];
@ -211,14 +220,26 @@ export class AppComponent implements OnInit {
position: 'left',
badge: true
};
this.sideBarItems.push(new MenuItem("community", "Community Info", "", "/" + this.community.communityId, false, [], [], {}, {name: 'badge'}, null, null, "/" + this.community.communityId + "/info"));
let communityInfo = new MenuItem("community", "Community Info", "", "/" + this.community.communityId, false, [], [], {}, {name: 'badge'}, null, null, "/" + this.community.communityId + "/info");
communityInfo.items = [
new MenuItem("profile", "Profile", "", "/" + this.community.communityId + "/info/profile", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/profile"),
new MenuItem("organizations", "Organizations", "", "/" + this.community.communityId + "/info/organizations", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/organizations"),
new MenuItem("projects", OpenaireEntities.PROJECTS, "", "/" + this.community.communityId + "/info/projects", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/projects"),
new MenuItem("content-providers", OpenaireEntities.DATASOURCES, "", "/" + this.community.communityId + "/info/content-providers", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/content-providers"),
new MenuItem("zenodo-communities", "Zenodo Communities ", "", "/" + this.community.communityId + "/info/zenodo-communities", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/zenodo-communities"),
new MenuItem("advanced-criteria", "Advanced Criteria", "", "/" + this.community.communityId + "/info/advanced-criteria", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/advanced-criteria")
]
if(this.community.type === 'community') {
communityInfo.items.splice(4, 0, new MenuItem("subjects", "Subjects", "", "/" + this.community.communityId + "/info/subjects", false, [], [], {}, null, null, null, "/" + this.community.communityId + "/info/subjects"))
}
this.sideBarItems.push(communityInfo);
this.sideBarItems.push(new MenuItem("users", "Users", "", "/" + this.community.communityId + "/users", false, [], [], {}, {name: 'group'}, null, null, "/" + this.community.communityId + "/users"));
this.sideBarItems.push(new MenuItem("admin-tools", "Pages & Menus", "", "/" + this.community.communityId + "/admin-tools/pages", false, [], [], {}, {name: 'description'}, null, null, "/" + this.community.communityId + "/admin-tools"));
this.sideBarItems.push(new MenuItem("customization", "Customization", "", "/" + this.community.communityId + "/customize-layout", false, [], [], {}, {name: 'brush'}));
if (this.community.type === 'ri') {
this.sideBarItems.push(new MenuItem("mining", "Mining", "", "/" + this.community.communityId + "/mining/manage-profiles", false, [], [], {}, {svg: mining.data}, null, null, "/" + this.community.communityId + "/mining"));
}
this.specialSideBarMenuItem = new MenuItem("back", "Manage communities", "", "/", false, [], null, {}, {name: 'search', class: 'uk-text-secondary'});
this.backItem = new MenuItem("back", "Manage Communities", "", "/", false, [], null, {}, {name: 'west'});
this.menuItems = [];
this.menuItems.push(new MenuItem("home", "Home",
@ -226,7 +247,7 @@ export class AppComponent implements OnInit {
, null, null, null, null, "_self")
);
this.menuItems.push(
new MenuItem("deposit", "Deposit", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/participate/participate/deposit/learn-how", "", false, [], ['/participate/deposit/learn-how'], null, null, null, null, null, "_self")
new MenuItem("deposit", "Deposit", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/participate/deposit/learn-how", "", false, [], ['/participate/deposit/learn-how'], null, null, null, null, null, "_self")
);
this.menuItems.push(
new MenuItem("link", "Link", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/participate/claim", "", false, [], ['/participate/claim'], null, null, null, null, null, "_self",
@ -256,7 +277,10 @@ export class AppComponent implements OnInit {
new MenuItem("", "Sources and methodology", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/content", "", false, [], ["/content"], null, null, null, null, null, "_self"),
new MenuItem("", "National Bulletins", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/national-bulletins", "", false, [], ["/national-bulletins"], null, null, null, null, null, "_self"),
new MenuItem("", "Subjects", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/subjects", "", false, [], ["/subjects"], null, null, null, null, null, "_self"),
new MenuItem("", "Projects and funding Opportunities", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/projects", "", false, [], ["/projects"], null, null, null, null, null, "_self")
new MenuItem("", "Projects and funding Opportunities", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/projects", "", false, [], ["/projects"], null, null, null, null, null, "_self"),
new MenuItem("", "Fields of Science", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/fields-of-science", "", false, [], ["/fields-of-science"], null, null, null, null, null, "_self"),
new MenuItem("", "Sustainable Development Goals", "https://"+(properties.environment == "beta" ? "beta." : "")+this.community.communityId+".openaire.eu/sdgs", "", false, [], ["/sdgs"], null, null, null, null, null, "_self"),
]
)
);
@ -306,7 +330,7 @@ export class AppComponent implements OnInit {
this.sideBarItems.push(new MenuItem("connect", "Connect Options", "", "/connect/admin-tools/pages", false, [], [], {}, {name: 'settings'}, null, null, '/connect/admin-tools'));
this.sideBarItems.push(new MenuItem("explore", "Explore Options", "", "/openaire/admin-tools/pages", false, [], [], {}, {name: 'settings'}, null, null, '/openaire/admin-tools'));
}
this.specialSideBarMenuItem = null;
this.backItem = null;
}
this.hasSidebar = this.hasSidebar && this.sideBarItems.length > 1;
}

@ -1 +1 @@
Subproject commit ac83453f7e3c261864d87f73533d785aae97f0fd
Subproject commit e30672043b03c607fb6c6c1c490d4fa34a772d3d

@ -0,0 +1,120 @@
import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
import {CommunityService} from "../../openaireLibrary/connect/community/community.service";
import {AdvancedCriteriaService} from "./advanced-criteria.service";
import {Subscription} from "rxjs";
import {SelectionCriteria} from "../../openaireLibrary/utils/entities/contentProvider";
import {
FullScreenModalComponent
} from "../../openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.component";
import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler";
import {CriteriaComponent} from "../content-providers/criteria/criteria.component";
import {CriteriaUtils} from "../content-providers/criteria-utils";
import {CommunityInfo} from "../../openaireLibrary/connect/community/communityInfo";
@Component({
selector: 'advanced-criteria',
template: `
<div page-content>
<div *ngIf="selectionCriteria" actions>
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-right@m uk-flex-center">
<button *ngIf="selectionCriteria.criteria.length === 0" (click)="openCriteria()" class="uk-button uk-button-default uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Add Criteria</span>
</button>
<button *ngIf="selectionCriteria.criteria.length > 0" (click)="openCriteria()" class="uk-button uk-button-default uk-flex uk-flex-middle">
<icon name="edit" [flex]="true"></icon>
<span class="uk-margin-small-left">Edit Criteria</span>
</button>
</div>
</div>
</div>
<div inner>
<div *ngIf="loading" class="uk-position-center">
<loading></loading>
</div>
<div *ngIf="!loading">
<div *ngIf="selectionCriteria?.criteria?.length > 0" class="uk-margin-small-bottom">
<div class="uk-text-meta uk-margin-small-bottom">Criteria</div>
<div [innerHTML]="criteriaUtils.getFiltersAsText(selectionCriteria.criteria)"></div>
</div>
<div *ngIf="selectionCriteria?.criteria?.length === 0" class="message">
<h5 class="uk-margin-small-bottom">No criteria yet</h5>
<i class="uk-display-block">
Add multiple constraints in AND to define a criterion: results that satisfy at least one of the criteria will be included in your community.
</i>
</div>
</div>
</div>
</div>
<fs-modal #filtersModal (okEmitter)="saveCriteria()" (cancelEmitter)="criteria.reset()"
[okButtonDisabled]="!criteria || criteria.disabled">
<div *ngIf="selectionCriteria" class="uk-container uk-container-large">
<criteria #criteria [height]="filtersModal.bodyHeight" [entityType]="'criterion'"
[entityTypePlural]="'criteria'" [selectionCriteria]="selectionCriteria">
<div no-criteria>
<h5 class="uk-margin-small-bottom">No Criteria yet</h5>
<i class="uk-display-block">
Add multiple constraints in AND to define a criterion: results that satisfy at least one of the criteria will be included in your community.
</i>
</div>
</criteria>
</div>
</fs-modal>
`
})
export class AdvancedCriteriaComponent implements OnInit, OnDestroy {
public loading = true;
public selectionCriteria: SelectionCriteria;
public community: CommunityInfo;
public criteriaUtils: CriteriaUtils = new CriteriaUtils();
private subscriptions: any[] = [];
@ViewChild('criteria') criteria: CriteriaComponent;
@ViewChild('filtersModal', { static: true }) filtersModal: FullScreenModalComponent;
constructor(private communityService: CommunityService,
private cdr: ChangeDetectorRef,
private advancedCriteriaService: AdvancedCriteriaService) {}
ngOnInit() {
this.loading = true;
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
this.community = community;
this.selectionCriteria = community.selectionCriteria;
this.loading = false;
}));
}
saveCriteria() {
let callback = (selectionCriteria): void => {
this.advancedCriteriaService.saveAdvancedCriteria(this.community.communityId, selectionCriteria).subscribe(() => {
this.criteria.reset();
this.criteria.loading = false;
NotificationHandler.rise('Filters have been <b>successfully updated</b>');
}, error => {
this.criteria.loading = false;
this.criteria.handeError('An error has been occurred. Try again later!', error);
});
}
this.loading = true;
this.criteria.save(callback);
}
public openCriteria() {
this.criteria.reset();
this.filtersModal.title = 'Criteria';
this.filtersModal.okButtonText = "Save";
this.filtersModal.back = true;
this.filtersModal.okButton = true;
this.filtersModal.open();
this.cdr.detectChanges();
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if(subscription instanceof Subscription) {
subscription.unsubscribe();
}
})
}
}

@ -0,0 +1,18 @@
import {NgModule} from "@angular/core";
import {CommonModule} from "@angular/common";
import {RouterModule} from "@angular/router";
import {AdvancedCriteriaComponent} from "./advanced-criteria.component";
import {PageContentModule} from "../../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {FullScreenModalModule} from "../../openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.module";
import {CriteriaModule} from "../content-providers/criteria/criteria.module";
import {IconsModule} from "../../openaireLibrary/utils/icons/icons.module";
import {LoadingModule} from "../../openaireLibrary/utils/loading/loading.module";
@NgModule({
imports: [CommonModule, RouterModule.forChild([
{path: '', component: AdvancedCriteriaComponent,}
]), PageContentModule, FullScreenModalModule, CriteriaModule, IconsModule, LoadingModule],
declarations: [AdvancedCriteriaComponent],
exports: [AdvancedCriteriaComponent]
})
export class AdvancedCriteriaModule {}

@ -0,0 +1,25 @@
import {Injectable} from "@angular/core";
import {SelectionCriteria} from "../../openaireLibrary/utils/entities/contentProvider";
import {Observable} from "rxjs";
import {CommunityInfo} from "../../openaireLibrary/connect/community/communityInfo";
import {HttpClient} from "@angular/common/http";
import {properties} from "../../../environments/environment";
import {map} from "rxjs/operators";
import {CommunityService} from "../../openaireLibrary/connect/community/community.service";
@Injectable({
providedIn: 'root'
})
export class AdvancedCriteriaService {
constructor(private httpClient: HttpClient,
private communityService: CommunityService) {
}
public saveAdvancedCriteria(communityId, selectionCriteria: SelectionCriteria): Observable<void> {
return this.httpClient.post(properties.communityAPI + communityId + '/advancedConstraint', selectionCriteria).pipe(map(community => {
this.communityService.updateAdvancedCriteria(this.communityService.parseCommunity(community).selectionCriteria);
}));
}
}

@ -1,16 +1,6 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Organizations
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="organizations"></community-info>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-center uk-flex-right@m">
<button *ngIf="!organizationsEnabled" class="uk-button uk-button-default uk-margin-right" [class.uk-disabled]="loading"
[disabled]="loading"

@ -113,6 +113,7 @@ export class AffiliationsComponent implements OnInit, OnDestroy {
deleteAffiliationOpen(index: number) {
this.index = index;
let affiliation: Affiliation = this.affiliations[index];
console.log(index, affiliation)
this.removeAffiliationModal.alertTitle = 'Delete Organization';
this.removeAffiliationModal.message = 'Do you want to remove <b>' +
affiliation.name + '</b> from Organizations?';
@ -164,7 +165,8 @@ export class AffiliationsComponent implements OnInit, OnDestroy {
removeAffiliation() {
this.loading = true;
this.affiliationService.deleteAffiliation(this.properties.communityAPI + this.community.communityId + '/organizations',
console.log(this.index, this.affiliations[this.index].id)
this.affiliationService.deleteAffiliation(this.properties.communityAPI + this.community.communityId + '/organizations?organizationName='+this.affiliations[this.index].name,
this.affiliations[this.index].id).subscribe((deleteOK) => {
this.affiliations.splice(this.index, 1);
if (this.currentPage.length === 0) {

@ -11,7 +11,6 @@ import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.mod
import {UtilitiesService} from '../../openaireLibrary/services/utilities.service';
import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module";
import {PageContentModule} from "../../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {CommunityInfoModule} from "../community-info/community-info.module";
import {IconsModule} from "../../openaireLibrary/utils/icons/icons.module";
import {NoLoadPaging} from "../../openaireLibrary/searchPages/searchUtils/no-load-paging.module";
import {LoadingModule} from "../../openaireLibrary/utils/loading/loading.module";
@ -22,7 +21,7 @@ import {PagingModule} from "../../openaireLibrary/utils/paging.module";
@NgModule({
imports: [
AffiliationsRoutingModule, CommonModule, FormsModule, RouterModule,
AlertModalModule, ReactiveFormsModule, InputModule, PageContentModule, CommunityInfoModule, IconsModule, NoLoadPaging, LoadingModule, UrlPrefixModule, PagingModule
AlertModalModule, ReactiveFormsModule, InputModule, PageContentModule, IconsModule, NoLoadPaging, LoadingModule, UrlPrefixModule, PagingModule
],
declarations: [
AffiliationsComponent

@ -11,13 +11,6 @@ import {CommunityService} from "../../openaireLibrary/connect/community/communit
template: `
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Links
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<users-tabs tab="claims"></users-tabs>
</div>
<div inner>

@ -11,6 +11,7 @@ import {ConnectCommunityGuard} from "../../openaireLibrary/connect/communityGuar
{path: 'projects', loadChildren: () => import('../projects/communityProjects.module').then(m => m.CommunityProjectsModule)},
{path: 'content-providers', loadChildren: () => import('../content-providers/communityContentProviders.module').then(m => m.CommunityContentProvidersModule)},
{path: 'zenodo-communities', loadChildren: () => import('../zenodo-communities/zenodo-communities.module').then(m => m.ZenodoCommunitiesModule)},
{path: 'advanced-criteria', loadChildren: () => import('../advanced-criteria/advanced-criteria.module').then(m => m.AdvancedCriteriaModule)},
{path: 'subjects', canActivateChild: [ConnectCommunityGuard], loadChildren: () => import('../subjects/subjects-edit-form/subjects-edit-form.module').then(m => m.SubjectsEditFormModule)},
])
],

@ -1,42 +0,0 @@
import {Component, Input, OnInit} from '@angular/core';
import {CommunityInfo} from '../../openaireLibrary/connect/community/communityInfo';
import {CommunityService} from '../../openaireLibrary/connect/community/community.service';
import {Subscription} from 'rxjs';
import {OpenaireEntities} from "../../openaireLibrary/utils/properties/searchFields";
@Component({
selector: 'community-info',
template: `
<ul *ngIf="community" class="uk-tab uk-margin-remove-bottom uk-margin-medium-top uk-flex uk-flex-center uk-flex-left@m" uk-tab>
<li [class.uk-active]="tab === 'profile'"><a routerLink="../profile">Profile</a></li>
<li [class.uk-active]="tab === 'organizations'"><a routerLink="../organizations">Organizations</a></li>
<li [class.uk-active]="tab === 'projects'"><a routerLink="../projects">{{openAIREEntities.PROJECTS}}</a></li>
<li [class.uk-active]="tab === 'content-providers'"><a routerLink="../content-providers">{{openAIREEntities.DATASOURCES}}</a></li>
<li *ngIf="community.type !='ri'" [class.uk-active]="tab === 'subjects'"><a routerLink="../subjects">Subjects</a></li>
<li [class.uk-active]="tab === 'zenodo-communities'"><a routerLink="../zenodo-communities">Zenodo Communities</a></li>
</ul>
`
})
export class CommunityInfoComponent implements OnInit {
@Input()
public type: string;
@Input()
public tab: "profile"| "organizations" | "projects" | "content-providers" | "subjects" | "zenodo-communities" = 'profile';
public community: CommunityInfo;
public openAIREEntities = OpenaireEntities;
private sub;
constructor(private communityService: CommunityService) {
}
ngOnInit() {
this.sub =this.communityService.getCommunityAsObservable().subscribe(community => {
this.community = community;
});
}
ngOnDestroy() {
if (this.sub instanceof Subscription) {
this.sub.unsubscribe();
}
}
}

@ -1,14 +0,0 @@
import {NgModule} from '@angular/core';
import {RouterModule} from "@angular/router";
import {CommonModule} from "@angular/common";
import {CommunityInfoComponent} from "./community-info.component";
@NgModule({
imports: [
CommonModule, RouterModule
],
declarations: [CommunityInfoComponent],
exports: [CommunityInfoComponent]
})
export class CommunityInfoModule {
}

@ -42,7 +42,7 @@ import {ClearCacheService} from "../../../../openaireLibrary/services/clear-cach
<div class="uk-width-1-1">
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
<div *ngIf="!communityFb.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-margin-xsmall-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"
@ -77,11 +77,21 @@ import {ClearCacheService} from "../../../../openaireLibrary/services/clear-cach
<!-- Full width error message -->
<div *ngIf="uploadError" class="uk-text-danger uk-margin-small-top uk-width-1-1">{{uploadError}}</div>
</div>
<div class="uk-width-1-2@m">
<div class="uk-width-1-3@m">
<div input [formInput]="communityFb.get('status')"
placeholder="Visibility status for your community's profile."
[options]="statuses" type="select"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="communityFb.get('claim')"
placeholder="Who can create links for your community"
[options]="claimOptions" type="select"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="communityFb.get('membership')"
placeholder="Who can join"
[options]="membershipOptions" type="select"></div>
</div>
</div>
</form>
`,
@ -90,10 +100,22 @@ import {ClearCacheService} from "../../../../openaireLibrary/services/clear-cach
export class EditCommunityComponent {
public communityFb: UntypedFormGroup;
public statuses: Option[] = [
{label: 'Visible', value: 'all'},
{label: 'Visible to managers', value: 'manager'},
// {label: 'Visible', value: 'all'},
{label: 'Visible', value: 'PUBLIC'},
// {label: 'Visible to managers', value: 'manager'},
{label: 'Visible to managers', value: 'RESTRICTED'},
{label: 'Hidden', value: 'hidden'}
]
public claimOptions: Option[] = [
{label: 'Logged in users', value: 'all'},
{label: 'Members only', value: 'membersOnly'},
{label: 'Managers only', value: 'managersOnly'}
]
public membershipOptions: Option[] = [
{label: 'Anyone can join', value: 'open'},
{label: 'By invitation', value: 'byInvitation'}
]
public community: CommunityInfo;
public isNew: boolean;
public properties: EnvProperties = properties
@ -133,6 +155,8 @@ export class EditCommunityComponent {
shortName: this.fb.control(this.community.shortTitle, Validators.required),
description: this.fb.control(this.community.description),
status: this.fb.control(this.community.status),
claim: this.fb.control(this.community.claim),
membership: this.fb.control(this.community.membership),
managers: this.fb.control(this.community.managers),
isUpload: this.fb.control(this.community.isUpload),
logoUrl: this.fb.control(this.community.logoUrl)

@ -11,19 +11,8 @@ import {Subscription} from "rxjs";
selector: 'community-profile',
template: `
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Community
Profile
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="profile"></community-info>
</div>
<div actions>
<div class="uk-container uk-section-xsmall">
<div actions class="uk-section-xsmall uk-margin-top">
<div class="uk-container">
<div class="uk-flex uk-flex-center uk-flex-right@m">
<button class="uk-button uk-button-default uk-margin-right"
(click)="reset()" [class.uk-disabled]="loading || !editCommunityComponent.dirty"

@ -5,7 +5,6 @@ import {PageContentModule} from "../../../openaireLibrary/dashboard/sharedCompon
import {ProfileComponent} from "./profile.component";
import {EditCommunityModule} from "./edit-community/edit-community.module";
import {LoadingModule} from "../../../openaireLibrary/utils/loading/loading.module";
import {CommunityInfoModule} from "../community-info.module";
@NgModule({
imports: [
@ -17,8 +16,7 @@ import {CommunityInfoModule} from "../community-info.module";
]),
PageContentModule,
EditCommunityModule,
LoadingModule,
CommunityInfoModule,
LoadingModule
],
declarations: [ProfileComponent],
exports: [ProfileComponent]

@ -31,7 +31,7 @@ import {ConnectRIGuard} from "../openaireLibrary/connect/communityGuard/connectR
{
path: 'customize-layout',
loadChildren: () => import('./customization/customization.module').then(m => m.CustomizationModule),
data: {hasSidebar: true, hasHeader: false}
data: {hasInternalSidebar: true, hasHeader: false}
},
{
path: 'user-info',

@ -13,17 +13,8 @@ declare var UIkit;
template: `
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-top info">
<img src="assets/common-assets/placeholder.png" class="uk-margin-right">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-h6">Admin Dashboard - Manage Options</div>
<h1 class="uk-h4 uk-margin-remove">Super Admin</h1>
</div>
</div>
<admin-tabs tab="customization" portal="connect"></admin-tabs>
</div>
<div inner>
<div class="uk-alert uk-alert-warning uk-margin-top ">
<div class="uk-text-large">Use only after connect deployment. And only if there are css updates!</div>
@ -51,6 +42,8 @@ declare var UIkit;
export class ConnectAdminCustomizationComponent implements OnInit {
private subscriptions: any[] = [];
savingChanges = false;
cssCreated: number = 0;
totalLayouts: number = 0;
community;
properties = properties;
@ -75,6 +68,7 @@ export class ConnectAdminCustomizationComponent implements OnInit {
let defaultCssIsSaved = false;
this.subscriptions.push(this.customizationService.getLayouts(properties, ).subscribe(layouts => {
this.totalLayouts = layouts ? layouts.length : 0;
for(let layout of layouts){
layout.date = date;
if(layout.portalPid == 'connect'){
@ -88,11 +82,13 @@ export class ConnectAdminCustomizationComponent implements OnInit {
}
}
if(!connectCssIsSaved){
this.totalLayouts++;
let layout = new Layout("connect", null);
layout.date = date;
this.callSaveAndCreate(layout, "connect")
}
if(!defaultCssIsSaved){
this.totalLayouts++;
let layout = new Layout("default", null);
layout.date = date;
this.callSaveAndCreate(layout, "connect")
@ -109,16 +105,22 @@ export class ConnectAdminCustomizationComponent implements OnInit {
pos: 'bottom-right'
});
this.cssCreated++;
if(this.cssCreated == this.totalLayouts) {
this.savingChanges = false;
}
}));
}));
}
purgeBrowserCache() {
this.savingChanges = true;
this.subscriptions.push(this.communitiesService.getCommunities(this.properties, this.properties.communityAPI + 'communities').subscribe(
communities => {
communities.forEach(community => {
this._clearCacheService.purgeBrowserCache("Layout added/ updated", community.communityId);
});
this.savingChanges = false;
}
));
this._clearCacheService.purgeBrowserCache("Layout added/ updated", "connect");

@ -10,7 +10,6 @@ import {ErrorMessagesModule} from '../../openaireLibrary/utils/errorMessages.mod
import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.module';
import {CommonModule} from '@angular/common';
import {PageContentModule} from "../../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {CommunityInfoModule} from "../community-info/community-info.module";
import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module";
import {SearchInputModule} from "../../openaireLibrary/sharedComponents/search-input/search-input.module";
import {NoLoadPaging} from "../../openaireLibrary/searchPages/searchUtils/no-load-paging.module";
@ -42,7 +41,6 @@ import {CriteriaModule} from "./criteria/criteria.module";
AlertModalModule,
SearchDataprovidersServiceModule,
PageContentModule,
CommunityInfoModule,
InputModule,
SearchInputModule,
RouterModule.forChild([

@ -1,18 +1,44 @@
import {Option} from "../../openaireLibrary/sharedComponents/input/input.component";
import {Criteria} from "../../openaireLibrary/utils/entities/contentProvider";
export class CriteriaUtils {
public static readonly fields: Option[] = [
{value: 'title', label: 'Title'},
public readonly fields: Option[] = [
{value: 'author', label: 'Author\'s name'},
{value: 'title', label: 'Title'},
{value: 'orcid', label: 'Author\'s ORCID'},
{value: 'contributor', label: 'Contributor'},
{value: 'description', label: 'Description'}
{value: 'description', label: 'Description'},
{value: 'subject', label: 'Subject'},
{value: 'fos', label: 'Field of Science'},
{value: 'sdg', label: 'SDG'},
{value: 'publisher', label: 'Publisher'},
{value: 'publicationyear', label: 'Publication Year'}
]
public static readonly verbs: Option[] = [
public readonly numericFields: string[] = ['publicationyear'];
public readonly verbs: Option[] = [
{value: 'contains', label: 'contains'},
{value: 'equals', label: 'equals'},
{value: 'not_contains', label: 'not contains'},
{value: 'not_equals', label: 'not equals'}
{value: 'not_equals', label: 'not equals'},
{value: 'starts_with', label: 'starts with'}
]
public readonly verbsForNumbers: Option[] = [
{value: 'equals', label: 'equals'},
{value: 'lesser_than', label: 'lesser than'},
{value: 'greater_than', label: 'greater than'}
]
public getFiltersAsText(criteria: Criteria[]): string {
let text = criteria.slice(0, 3).map((criterion, index) => (index + 1) + ". " + criterion.constraint.map(constraint => {
let field = this.fields.find(field => field.value === constraint.field)?.label;
let matchCase = false;
if (!constraint.verb.includes('_caseinsensitive')) {
matchCase = true;
}
let verb = [...this.verbs,...this.verbsForNumbers].find(verb => verb.value === constraint.verb.replace("_caseinsensitive", "")).label;
let value = '"' + constraint.value + '"' + (matchCase ? " (Match case)" : "");
return field + " " + verb + " " + value;
}).join(" <b>and</b> "));
return text.join("<br>");
}
}

@ -1,120 +1,121 @@
<div class="uk-section uk-position-relative" style="min-height: 60vh">
<div class="uk-position-relative" style="min-height: 60vh">
<div *ngIf="loading" class="uk-position-center">
<loading></loading>
</div>
<ng-container *ngIf="!loading">
<div class="uk-flex uk-flex-center uk-margin-medium-bottom">
<a (click)="addCriteria()" class="uk-flex uk-flex-middle uk-button uk-button-primary"
uk-tooltip="<div>Add filter to limit research results.<br>Results which satisfy any of the selected filters will be included in your community.</div>">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Add filter</span>
</a>
</div>
<div *ngIf="criteria.length == 0" class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div *ngIf="dataProvider">No filters for {{dataProvider.officialname}}.</div>
<div>If no filters are specified, all {{openaireEntities.RESULTS | lowercase}} of this {{openaireEntities.DATASOURCE | lowercase}} will be included in your
{{openaireEntities.COMMUNITY | lowercase}}.
<div class="criteria uk-overflow-auto uk-position-relative" [ngStyle]="{'height.px': criteriaHeight?criteriaHeight:null}">
<div *ngIf="criteria.length == 0" class="uk-text-center uk-position-center">
<ng-content select="[no-criteria]"></ng-content>
</div>
</div>
<form *ngIf="criteria.length > 0" [formGroup]="selectionCriteria">
<div formArrayName="criteria" class="uk-margin-bottom">
<no-load-paging (pageChange)="updatePage($event)" [page]="page" [totalResults]="criteria.length"
[pageSize]="pageSize" [type]="'filter' + (criteria.length > 1?'s':'')">
</no-load-paging>
<ul class="uk-list uk-list-xlarge uk-margin-top uk-margin-bottom">
<li *ngFor="let criterion of currentPage; let i=index">
<div [formGroupName]="getIndex(i).toString()" class="uk-flex">
<h3 class="uk-padding uk-margin-remove-bottom uk-margin-top">
{{getIndex(i) + 1}}
</h3>
<div class="uk-width-expand uk-padding-small criterion" formArrayName="constraint">
<div class="uk-flex-middle uk-grid uk-margin-small-bottom uk-visible@l" uk-grid>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Field</label>
</div>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Operator</label>
</div>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Term</label>
</div>
<div class="uk-width-expand uk-text-truncate">
<label class="uk-text-bold uk-text-uppercase">Match Case</label>
</div>
</div>
<div *ngFor="let constraint of getConstraint(getIndex(i)).controls; let j=index" [formGroupName]="j.toString()"
class="uk-margin-bottom uk-hidden@l">
<div class="uk-flex-middle uk-grid-small uk-margin-medium-bottom" uk-grid>
<div class="uk-flex uk-flex-right uk-width-1-1">
<button class="uk-close uk-icon" (click)="removeConstraint(getIndex(i), j)">
<icon name="close" ratio="1.5" [flex]="true"
[attr.uk-tooltip]="(getConstraint(getIndex(i)).length === 1?'By removing this constraint, the filter will be removed too':null)"></icon>
</button>
<form *ngIf="criteria.length > 0" [formGroup]="selectionCriteriaForm">
<div formArrayName="criteria" class="uk-margin-bottom">
<ul class="uk-list uk-list-xlarge uk-margin-top uk-margin-bottom">
<li *ngFor="let criterion of criteria.controls; let i=index">
<div [id]="'criterion-' + i.toString()" [formGroupName]="i.toString()" class="uk-flex">
<h3 class="uk-padding uk-margin-remove-bottom uk-margin-top">
{{i + 1}}
</h3>
<div class="uk-width-expand uk-padding-small uk-border uk-border-rounded" formArrayName="constraint">
<div class="uk-flex-middle uk-grid uk-margin-small-bottom uk-visible@l" uk-grid>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Field</label>
</div>
<div class="uk-width-1-1" input type="select" inputClass="border-bottom" [placeholder]="{static: true, label: 'Choose a field'}"
[options]="fields" [formInput]="constraint.get('field')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Field:</label>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Operator</label>
</div>
<div class="uk-width-1-1" input type="select" inputClass="border-bottom"
[options]="verbs" [formInput]="constraint.get('verb')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Operator:</label>
<div class="uk-width-1-4">
<label class="uk-text-uppercase uk-text-bold">Term</label>
</div>
<div class="uk-width-1-1" input [placeholder]="{static: true, label: 'Type a keyword'}"
[formInput]="constraint.get('value')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Term:</label>
<div class="uk-width-expand uk-text-truncate">
<label class="uk-text-bold uk-text-uppercase">Match Case</label>
</div>
<div class="uk-width-1-1">
<div class="uk-grid" uk-grid>
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Match Case</label>
<div class="uk-width-expand">
<mat-slide-toggle [checked]="constraint.get('verb_suffix').value === ''"
[attr.uk-tooltip]="(constraint.get('verb_suffix').value === ''?('Only \'\'' + constraint.get('value').value + '\'\' matches'):
</div>
<div *ngFor="let constraint of getConstraint(i).controls; let j=index" [formGroupName]="j.toString()"
class="uk-margin-bottom uk-hidden@l">
<div class="uk-flex-middle uk-grid-small uk-margin-medium-bottom" uk-grid>
<div class="uk-flex uk-flex-right uk-width-1-1">
<button class="uk-close uk-icon" (click)="removeConstraint(i, j)">
<icon name="close" ratio="1.5" [flex]="true"
[attr.uk-tooltip]="(getConstraint(i).length === 1?'By removing this constraint, the ' + entityType + ' will be removed too':null)"></icon>
</button>
</div>
<div class="uk-width-1-1" input type="select" inputClass="border-bottom" [placeholder]="{static: true, label: 'Choose a field'}"
[options]="criteriaUtils.fields" [formInput]="constraint.get('field')" (valueChange)="resetFieldWhenValueChange(constraint)">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Field:</label>
</div>
<div *ngIf="criteriaUtils.numericFields.indexOf(constraint.get('field').value) == -1" class="uk-width-1-1" input type="select" inputClass="border-bottom"
[options]="criteriaUtils.verbs" [formInput]="constraint.get('verb')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Operator:</label>
</div>
<div *ngIf="criteriaUtils.numericFields.indexOf(constraint.get('field').value) != -1" class="uk-width-1-1" input type="select" inputClass="border-bottom"
[options]="criteriaUtils.verbsForNumbers" [formInput]="constraint.get('verb')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Operator:</label>
</div>
<div class="uk-width-1-1" input [placeholder]="{static: true, label: 'Type a keyword'}"
[formInput]="constraint.get('value')">
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Term:</label>
</div>
<div class="uk-width-1-1">
<div class="uk-grid" uk-grid>
<label class="uk-text-uppercase uk-text-bold uk-width-1-3 uk-text-truncate">Match Case</label>
<div class="uk-width-expand">
<mat-slide-toggle [checked]="constraint.get('verb_suffix').value === ''"
[attr.uk-tooltip]="(constraint.get('verb_suffix').value === ''?('Only \'\'' + constraint.get('value').value + '\'\' matches'):
('Both \'\'' + constraint.get('value').value.toUpperCase() + '\'\' and \'\'' + constraint.get('value').value.toLowerCase() + '\'\' match'))"
(change)="caseSensitive($event, constraint)"></mat-slide-toggle>
(change)="caseSensitive($event, constraint)"></mat-slide-toggle>
</div>
</div>
</div>
</div>
</div>
</div>
<div *ngFor="let constraint of getConstraint(getIndex(i)).controls; let j=index"
[formGroupName]="j.toString()" class="uk-margin-bottom uk-visible@l">
<div class="uk-flex uk-flex-middle uk-grid" uk-grid>
<div class="uk-width-1-4" input type="select" inputClass="border-bottom" [placeholder]="{static: true, label: 'Choose a field'}"
[options]="fields" [formInput]="constraint.get('field')"></div>
<div class="uk-width-1-4" input type="select" inputClass="border-bottom"
[options]="verbs" [formInput]="constraint.get('verb')"></div>
<div class="uk-width-1-4" input [placeholder]="{static: true, label: 'Type a keyword'}"
[formInput]="constraint.get('value')"></div>
<div class="uk-width-expand">
<mat-slide-toggle [checked]="constraint.get('verb_suffix').value === ''" class="uk-margin-left"
[attr.uk-tooltip]="(constraint.get('verb_suffix').value === ''?('Only \'\'' + constraint.get('value').value + '\'\' matches'):
<div *ngFor="let constraint of getConstraint(i).controls; let j=index"
[formGroupName]="j.toString()" class="uk-margin-bottom uk-visible@l">
<div class="uk-flex uk-flex-middle uk-grid" uk-grid>
<div class="uk-width-1-4" input type="select" inputClass="border-bottom" [placeholder]="{static: true, label: 'Choose a field'}"
[options]="criteriaUtils.fields" [formInput]="constraint.get('field')"></div>
<div *ngIf="criteriaUtils.numericFields.indexOf(constraint.get('field').value) == -1" class="uk-width-1-4" input type="select" inputClass="border-bottom"
[options]="criteriaUtils.verbs" [formInput]="constraint.get('verb')"></div>
<div *ngIf="criteriaUtils.numericFields.indexOf(constraint.get('field').value) != -1" class="uk-width-1-4" input type="select" inputClass="border-bottom"
[options]="criteriaUtils.verbsForNumbers" [formInput]="constraint.get('verb')"></div>
<div *ngIf="constraint.get('field').value !== 'fos' && constraint.get('field').value !== 'sdg'" class="uk-width-1-4" inputClass="flat small" input [placeholder]="{static: true, label: 'Type a keyword'}"
[formInput]="constraint.get('value')"></div>
<div *ngIf="constraint.get('field').value === 'fos'" class="uk-width-1-4" inputClass="flat small" input [placeholder]="{static: true, label: 'Choose a FoS'}"
[formInput]="constraint.get('value')" type="select" [options]="fos"></div>
<div *ngIf="constraint.get('field').value === 'sdg'" class="uk-width-1-4" inputClass="flat small" input [placeholder]="{static: true, label: 'Choose a FoS'}"
[formInput]="constraint.get('value')" type="select" [options]="sdg"></div>
<div class="uk-width-expand">
<mat-slide-toggle [checked]="constraint.get('verb_suffix').value === ''" class="uk-margin-left"
[attr.uk-tooltip]="(constraint.get('verb_suffix').value === ''?('Only \'\'' + constraint.get('value').value + '\'\' matches'):
('Both \'\'' + constraint.get('value').value.toUpperCase() + '\'\' and \'\'' + constraint.get('value').value.toLowerCase() + '\'\' match'))"
(change)="caseSensitive($event, constraint)"></mat-slide-toggle>
</div>
<div class="uk-flex uk-flex-center">
<button class="uk-close uk-icon" (click)="removeConstraint(getIndex(i), j)">
<icon name="close" ratio="1.5" [flex]="true"
[attr.uk-tooltip]="(getConstraint(getIndex(i)).length === 1?'By removing this constraint, the filter will be removed too':null)"></icon>
</button>
(change)="caseSensitive($event, constraint)"></mat-slide-toggle>
</div>
<div class="uk-flex uk-flex-center">
<button class="uk-close uk-icon" (click)="removeConstraint(i, j)">
<icon name="close" ratio="1.5" [flex]="true"
[attr.uk-tooltip]="(getConstraint(i).length === 1?'By removing this constraint, the ' + entityType + ' will be removed too':null)"></icon>
</button>
</div>
</div>
</div>
</div>
<div class="uk-margin-top uk-width-1-1 uk-flex uk-flex-center uk-flex-left@l">
<a (click)="addConstraint(getIndex(i))" class="uk-flex uk-flex-middle uk-button uk-button-link">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Add Constraint</span>
</a>
<div class="uk-margin-top uk-width-1-1 uk-flex uk-flex-center uk-flex-left@l">
<a (click)="addConstraint(i)" class="uk-flex uk-flex-middle uk-button uk-button-link">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Add Constraint</span>
</a>
</div>
</div>
</div>
</div>
</li>
</ul>
<div class="uk-margin-small-top">
<paging-no-load [currentPage]="page" [totalResults]="criteria.length" [size]="pageSize"
(pageChange)="updatePage($event)" customClasses="uk-flex-right@m uk-flex-center">
</paging-no-load>
</li>
</ul>
</div>
</div>
</form>
</form>
</div>
<div class="uk-flex uk-flex-center uk-margin-top">
<a (click)="addCriteria()" class="uk-flex uk-flex-middle uk-button uk-button-primary"
[attr.uk-tooltip]="'<div>Add a ' + entityType + ' to limit research results.<br>Results which satisfy any of the selected ' + entityTypePlural + ' will be included in your ' + openaireEntities.COMMUNITY + '.</div>'">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">Add {{entityType}}</span>
</a>
</div>
</ng-container>
</div>

@ -1,8 +1,3 @@
@import (reference) "~src/assets/openaire-theme/less/_import-variables.less";
.criterion {
border: @global-border solid @global-border-width;
border-radius: @global-border-radius;
max-height: 400px;
overflow: auto;
.criteria {
padding-right: 20px;
}

@ -1,93 +1,121 @@
import {ChangeDetectorRef, Component, Input, OnInit} from '@angular/core';
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
import {
Constraint,
ContentProvider,
Criteria,
SelectionCriteria
} from '../../../openaireLibrary/utils/entities/contentProvider';
AfterViewInit,
ChangeDetectorRef,
Component,
Input,
OnChanges,
OnDestroy,
OnInit,
SimpleChanges
} from '@angular/core';
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
import {Constraint, Criteria, SelectionCriteria} from '../../../openaireLibrary/utils/entities/contentProvider';
import {AbstractControl, UntypedFormArray, UntypedFormBuilder, UntypedFormGroup, Validators} from '@angular/forms';
import {ManageCommunityContentProvidersService} from '../../../services/manageContentProviders.service';
import {properties} from "../../../../environments/environment";
import {Option} from "../../../openaireLibrary/sharedComponents/input/input.component";
import {MatSlideToggleChange} from "@angular/material/slide-toggle";
import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class";
import {CriteriaUtils} from "../criteria-utils";
import {NotificationHandler} from "../../../openaireLibrary/utils/notification-handler";
import {OpenaireEntities} from "../../../openaireLibrary/utils/properties/searchFields";
import {ISVocabulariesService} from "../../../openaireLibrary/utils/staticAutoComplete/ISVocabularies.service";
import {Subscription} from "rxjs";
@Component({
selector: 'criteria',
templateUrl: 'criteria.component.html',
styleUrls: ['criteria.component.less']
})
export class CriteriaComponent implements OnInit {
export class CriteriaComponent implements OnInit, OnChanges, AfterViewInit, OnDestroy {
@Input()
public entityType: string = 'filter';
@Input()
public entityTypePlural: string = 'filters';
@Input()
public selectionCriteria: SelectionCriteria;
@Input()
public dataProvider: ContentProvider;
public selectionCriteria: UntypedFormGroup;
public height: number = 0;
public criteriaHeight: number = 0;
public selectionCriteriaForm: UntypedFormGroup;
public properties: EnvProperties = properties;
public fields: Option[] = CriteriaUtils.fields;
public verbs: Option[] = CriteriaUtils.verbs;
public criteriaUtils: CriteriaUtils = new CriteriaUtils();
public fos: string[] = [];
public sdg: string[] = [];
public loading = true;
/** Paging */
public page: number = 1;
public pageSize: number = 5;
public openaireEntities = OpenaireEntities;
private subscriptions: any[] = [];
constructor(private manageCommunityContentProvidersService: ManageCommunityContentProvidersService,
private cdr: ChangeDetectorRef,
constructor(private cdr: ChangeDetectorRef, private vocabulariesService: ISVocabulariesService,
private fb: UntypedFormBuilder) {
}
ngOnInit() {
this.reset();
this.loading = false;
this.subscriptions.push(this.vocabulariesService.getVocabularyByType('fos', null, properties).subscribe((fos: any[]) => {
this.fos = fos.map(element => element.id);
}));
this.subscriptions.push(this.vocabulariesService.getVocabularyByType('sdg', null, properties).subscribe((sdg: any[]) => {
this.sdg = sdg.map(element => element.id);
}));
}
reset() {
this.page = 1;
if (this.dataProvider) {
this.selectionCriteria = this.fb.group({
criteria: this.fb.array([])
});
let selectionCriteria = this.dataProvider.selectioncriteria;
if (selectionCriteria) {
selectionCriteria.criteria.forEach(criterion => {
let constraintArray: UntypedFormArray = this.fb.array([]);
criterion.constraint.forEach(constraint => {
constraintArray.push(this.fb.group({
field: this.fb.control(constraint.field, Validators.required),
verb: this.fb.control(this.removeSuffix(constraint.verb), Validators.required),
value: this.fb.control(constraint.value, Validators.required),
verb_suffix: this.fb.control(this.getSuffix(constraint.verb))
}));
});
this.criteria.push(this.fb.group({
constraint: constraintArray
}));
});
}
ngOnChanges(changes: SimpleChanges) {
if(changes.selectionCriteria){
this.reset();
}
this.calculateMaxHeight();
}
get disabled() {
return this.loading || !this.dirty || this.selectionCriteria.invalid;
ngAfterViewInit() {
this.calculateMaxHeight();
}
get currentPage(): AbstractControl[] {
if (this.criteria) {
return this.criteria.controls.slice((this.page - 1) * this.pageSize, this.page * this.pageSize);
} else {
return [];
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
calculateMaxHeight() {
if(this.height) {
if(this.height > 0) {
/* Element height - margins(20 + 20) - button height(42) */
this.criteriaHeight = this.height - 40 - 42;
this.cdr.detectChanges();
}
}
}
reset() {
this.selectionCriteriaForm = this.fb.group({
criteria: this.fb.array([])
});
if (this.selectionCriteria?.criteria) {
this.selectionCriteria.criteria.forEach(criterion => {
let constraintArray: UntypedFormArray = this.fb.array([]);
criterion.constraint.forEach(constraint => {
constraintArray.push(this.fb.group({
field: this.fb.control(constraint.field, Validators.required),
verb: this.fb.control(this.removeSuffix(constraint.verb), Validators.required),
value: this.fb.control(constraint.value, Validators.required),
verb_suffix: this.fb.control(this.getSuffix(constraint.verb))
}));
});
this.criteria.push(this.fb.group({
constraint: constraintArray
}));
});
}
}
getIndex(index: number): number {
return (this.page - 1)*this.pageSize + index;
get disabled() {
return this.loading || !this.dirty || this.selectionCriteriaForm.invalid;
}
public get criteria(): UntypedFormArray {
return this.selectionCriteria.get('criteria') as UntypedFormArray;
return this.selectionCriteriaForm.get('criteria') as UntypedFormArray;
}
public getConstraint(i: number): UntypedFormArray {
@ -103,11 +131,9 @@ export class CriteriaComponent implements OnInit {
verb_suffix: this.fb.control('_caseinsensitive')
})
]);
this.criteria.insert(0, this.fb.group({
constraint: constraintArray
}));
this.page = 1;
this.criteria.push(this.fb.group({constraint: constraintArray}));
this.cdr.detectChanges();
document.getElementById('criterion-' + (this.criteria.length - 1).toString()).scrollIntoView({behavior: 'smooth'});
}
public addConstraint(i: number) {
@ -126,25 +152,22 @@ export class CriteriaComponent implements OnInit {
constraintArray.removeAt(j);
if (constraintArray.length === 0) {
this.criteria.removeAt(i);
while(this.currentPage.length === 0 && this.page > 0) {
this.page--;
}
}
this.cdr.detectChanges();
}
get dataProviderCriteria(): Criteria[] {
return (this.dataProvider && this.dataProvider.selectioncriteria && this.dataProvider.selectioncriteria.criteria)?this.dataProvider.selectioncriteria.criteria:[];
get criteriaArray(): Criteria[] {
return (this.selectionCriteria?.criteria) ? this.selectionCriteria?.criteria : [];
}
get dirty() {
if(!this.dataProvider || !this.criteria) {
if (!this.selectionCriteria && !this.criteria) {
return false;
} else if(this.criteria.length !== this.dataProviderCriteria.length) {
} else if (this.criteria.length !== this.criteriaArray.length) {
return true;
} else {
return this.dataProviderCriteria.filter((criterion, i) => {
if(criterion.constraint.length !== this.getConstraint(i).length) {
return this.criteriaArray.filter((criterion, i) => {
if (criterion.constraint.length !== this.getConstraint(i).length) {
return true;
} else {
let temp = this.getConstraint(i).value;
@ -156,23 +179,10 @@ export class CriteriaComponent implements OnInit {
}
}
save(callback: Function = null) {
if (this.selectionCriteria.valid) {
save(callback: (selectionCriteria) => void = null) {
if (this.selectionCriteriaForm.valid) {
this.loading = true;
this.dataProvider.selectioncriteria = this.parseForm(this.selectionCriteria.value);
this.manageCommunityContentProvidersService.saveContentProvider(this.properties, this.dataProvider).subscribe(() => {
this.reset();
if(callback) {
callback();
}
this.loading = false;
NotificationHandler.rise('Filters have been <b>successfully updated</b>');
}, error => {
this.loading = false;
this.handeError('An error has been occurred. Try again later!', error);
});
} else {
this.handeError('An error has been occurred. Try again later!');
callback(this.parseForm(this.selectionCriteriaForm.value));
}
}
@ -182,7 +192,7 @@ export class CriteriaComponent implements OnInit {
}
caseSensitive(event: MatSlideToggleChange, constraint: AbstractControl) {
if(event.checked) {
if (event.checked) {
constraint.get('verb_suffix').setValue('');
} else {
constraint.get('verb_suffix').setValue('_caseinsensitive');
@ -194,7 +204,7 @@ export class CriteriaComponent implements OnInit {
}
getSuffix(verb: string) {
if(verb.includes('_caseinsensitive')) {
if (verb.includes('_caseinsensitive')) {
return '_caseinsensitive';
} else {
return '';
@ -215,9 +225,14 @@ export class CriteriaComponent implements OnInit {
})
return selectionCriteria;
}
public updatePage(event) {
this.page = event.value;
HelperFunctions.scroll();
resetFieldWhenValueChange(constraint){
// if field not numeric, but verb is numeric clear the verb
if(this.criteriaUtils.numericFields.indexOf(constraint.get('field').value) == -1 && this.criteriaUtils.verbs.indexOf(constraint.get('verb').value)){
constraint.get('verb').setValue(this.criteriaUtils.verbs[0].value);
}
if(this.criteriaUtils.numericFields.indexOf(constraint.get('field').value) != -1 && this.criteriaUtils.numericFields.indexOf(constraint.get('verb').value)){
constraint.get('verb').setValue(this.criteriaUtils.verbsForNumbers[0].value);
}
}
}

@ -1,4 +1,4 @@
import {Component, OnInit, ViewChild} from '@angular/core';
import {ChangeDetectorRef, Component, OnInit, ViewChild} from '@angular/core';
import {RemoveContentProvidersComponent} from './remove-content-providers.component';
import {Title} from '@angular/platform-browser';
import {
@ -13,6 +13,8 @@ import {CommunityService} from "../../openaireLibrary/connect/community/communit
import {ContentProvider} from "../../openaireLibrary/utils/entities/contentProvider";
import {OpenaireEntities} from "../../openaireLibrary/utils/properties/searchFields";
import {CriteriaComponent} from "./criteria/criteria.component";
import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler";
import {ManageCommunityContentProvidersService} from "../../services/manageContentProviders.service";
@Component({
selector: 'manage-content-providers',
@ -24,12 +26,22 @@ import {CriteriaComponent} from "./criteria/criteria.component";
(communityContentProvidersChanged)="communityContentProvidersChanged($event)">
</remove-content-providers>
<fs-modal #addContentProvidersModal>
<add-content-providers #addContentProviders [communityContentProviders]="communityContentProviders" [community]="community"
<add-content-providers #addContentProviders [communityContentProviders]="communityContentProviders"
[community]="community"
(communityContentProvidersChanged)="communityContentProvidersChanged($event)"></add-content-providers>
</fs-modal>
<fs-modal #filtersModal (okEmitter)="saveCriteria()" (cancelEmitter)="criteria.reset()" [okButtonDisabled]="criteria && criteria.disabled">
<div class="uk-container">
<criteria #criteria *ngIf="contentProvider" [dataProvider]="contentProvider"></criteria>
<fs-modal #filtersModal (okEmitter)="saveCriteria()" (cancelEmitter)="criteria.reset()"
[okButtonDisabled]="criteria && criteria.disabled">
<div class="uk-container uk-container-large">
<criteria #criteria *ngIf="dataProvider" [height]="filtersModal.bodyHeight"
[selectionCriteria]="dataProvider.selectioncriteria">
<div no-criteria>
<h5 class="uk-margin-small-bottom">No Filters for {{dataProvider.officialname}} yet</h5>
<i class="uk-display-block">If no Filters are specified, all {{openaireEntities.RESULTS | lowercase}} of this {{openaireEntities.DATASOURCE | lowercase}} will be included in your
{{openaireEntities.COMMUNITY | lowercase}}.
</i>
</div>
</criteria>
</div>
</fs-modal>
`
@ -45,11 +57,14 @@ export class ManageContentProvidersComponent implements OnInit {
public showLoadingInRemove: boolean = true;
public body: string = "Send from page";
public properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities;
public community: CommunityInfo;
public contentProvider: ContentProvider;
public dataProvider: ContentProvider;
constructor(private title: Title,
private communityService: CommunityService) {
private cdr: ChangeDetectorRef,
private communityService: CommunityService,
private manageCommunityContentProvidersService: ManageCommunityContentProvidersService) {
}
ngOnInit() {
@ -80,17 +95,27 @@ export class ManageContentProvidersComponent implements OnInit {
}
public openCriteria(contentProvider: ContentProvider) {
this.contentProvider = contentProvider;
this.dataProvider = contentProvider;
this.filtersModal.title = 'Filters';
this.filtersModal.okButtonText = "Save";
this.filtersModal.back = true;
this.filtersModal.okButton = true;
this.filtersModal.open();
this.cdr.detectChanges();
}
public saveCriteria() {
let callback: Function = () => {
this.removeContentProvidersComponent.getCommunityContentProviders();
let callback = (selectionCriteria): void => {
this.dataProvider.selectioncriteria = selectionCriteria;
this.manageCommunityContentProvidersService.saveContentProvider(this.properties, this.dataProvider).subscribe(() => {
this.criteria.reset();
this.removeContentProvidersComponent.getCommunityContentProviders();
this.criteria.loading = false;
NotificationHandler.rise('Filters have been <b>successfully updated</b>');
}, error => {
this.criteria.loading = false;
this.criteria.handeError('An error has been occurred. Try again later!', error);
});
}
this.removeContentProvidersComponent.loading = true;
this.criteria.save(callback);

@ -1,16 +1,6 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage <span class="uk-text-capitalize">{{openAIREEntities.DATASOURCES}}</span>
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="content-providers"></community-info>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-middle uk-grid" uk-grid>
<div search-input [expandable]="true" [searchControl]="filterForm.get('keyword')" searchInputClass="outer"
[placeholder]="'Search ' + openAIREEntities.DATASOURCES" [disabled]="loading"
@ -66,7 +56,7 @@
</h6>
<div *ngIf="item.selectioncriteria?.criteria?.length > 0" class="uk-margin-small-bottom uk-text-small">
<div class="uk-text-meta uk-margin-small-bottom">Filters</div>
<div [innerHTML]="getFiltersAsText(item.selectioncriteria.criteria)"></div>
<div [innerHTML]="criteriaUtils.getFiltersAsText(item.selectioncriteria.criteria)"></div>
<div *ngIf="item.selectioncriteria.criteria.length > 3" class="uk-margin-small-top">
<a class="uk-link view-more-less-link" (click)="openCriteria(item)">View all {{item.selectioncriteria.criteria.length}} filters</a>
</div>

@ -38,8 +38,7 @@ export class RemoveContentProvidersComponent implements OnInit {
private selectedCommunityContentProvider: any;
@ViewChild('deleteModal') deleteModal: AlertModal;
/** Criteria */
private fields = CriteriaUtils.fields;
private verbs = CriteriaUtils.verbs;
public criteriaUtils: CriteriaUtils = new CriteriaUtils();
/** Paging */
page: number = 1;
resultsPerPage: number = properties.resultsPerPage;
@ -81,22 +80,9 @@ export class RemoveContentProvidersComponent implements OnInit {
});
}
getFiltersAsText(criteria: Criteria[]): string {
let text = criteria.slice(0, 3).map((criterion, index) => (index + 1) + ". " + criterion.constraint.map(constraint => {
let field = this.fields.find(field => field.value === constraint.field)?.label;
let matchCase = false;
if (!constraint.verb.includes('_caseinsensitive')) {
matchCase = true;
}
let verb = this.verbs.find(verb => verb.value === constraint.verb.replace("_caseinsensitive", "")).label;
let value = '"' + constraint.value + '"' + (matchCase ? " (Match case)" : "");
return field + " " + verb + " " + value;
}).join(" <b>and</b> "));
return text.join("<br>");
}
public confirmedDeleteContentProvider() {
this.subscriptions.push(this._manageCommunityContentProvidersService.removeContentProvider(this.properties, this.community.communityId, this.selectedCommunityContentProvider.id).subscribe(
console.log(this.selectedCommunityContentProvider)
this.subscriptions.push(this._manageCommunityContentProvidersService.removeContentProvider(this.properties, this.community.communityId, this.selectedCommunityContentProvider.openaireId).subscribe(
() => {
let index = this.communityContentProviders.indexOf(this.selectedCommunityContentProvider);
this.communityContentProviders.splice(index, 1);

@ -9,60 +9,65 @@ declare var UIkit;
selector: 'background-upload',
template: `
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
<div *ngIf="!background.imageFile" class=" upload uk-text-center uk-height-small uk-flex uk-flex-middle uk-flex-center uk-text-uppercase">
<div *ngIf="!background.imageFile"
class=" upload uk-text-center uk-height-small uk-flex uk-flex-middle uk-flex-center uk-text-uppercase">
<span uk-icon="icon: cloud-upload"></span>
<div uk-form-custom>
<span class="uk-link uk-margin-small-left" (click)="file.click()">upload image</span>
<span class="uk-link uk-margin-small-left" (click)="file.click()">upload image</span>
</div>
</div>
<div *ngIf="background.imageFile" class="uk-width-1-1 uk-flex uk-flex-middle ">
<div class="uk-width-1-1 uk-height-small" style = "background-size:cover"
[style.background-image]=" getUrl()">
<div *ngIf="background.imageFile" class="uk-width-1-1 uk-flex uk-flex-middle ">
<div class="uk-width-1-1 uk-height-small" style="background-size:cover"
[style.background-image]=" getUrl()">
<a (click)="removePhoto()" uk-tooltip="Remove" class="uk-float-right uk-border-rounded uk-margin-top uk-margin-right uk-background-muted uk-button uk-button-link">
<icon name="delete" [defaultSize]="true" [flex]="true"></icon>
</a>
</div>
<a (click)="removePhoto()" uk-tooltip="Remove"
class="uk-float-right uk-border-rounded uk-margin-top uk-margin-right uk-background-muted uk-button uk-button-link">
<icon name="delete" [defaultSize]="true" [flex]="true"></icon>
</a>
<div class="uk-text-small uk-margin-large-top uk-text-center" [class.uk-light]="!light">Lorem ipsum dolor sit amet...</div>
</div>
</div>
<div *ngIf="background.imageFile" class="uk-margin-top">
<div class="uk-text-bold uk-text-uppercase uk-text-meta uk-margin-small-bottom uk-margin-large-top">position</div>
<div class="uk-width-expand uk-padding-remove-left" input type="select" inputClass="flat x-small" [(value)]="background.position"
[options]="['top','center','bottom']" >
</div>
<div class="uk-width-expand uk-padding-remove-left" input type="select" inputClass="flat x-small"
[(value)]="background.position"
[options]="['top','center','bottom']">
</div>
</div>
`,
styles:[`
.upload{
border: 1px dotted grey;
}
styles: [`
.upload {
border: 1px dotted grey;
}
`]
})
export class BackgroundUploadComponent implements OnInit {
@Input() label:string = "";
@Input() label: string = "";
@Input() background;
@Input() oldBackground;
// @Input() light:boolean;
@Input() communityId:string = "";
@Input() communityId: string = "";
@Input() light:boolean; //fonts mode
public file: File;
// public photo: string | ArrayBuffer;
private maxsize: number = 2000 * 1024;
properties;
private subscriptions: any[] = [];
constructor(private utilsService: UtilitiesService) {
}
ngOnInit() {
this.properties = properties;
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
@ -70,30 +75,29 @@ export class BackgroundUploadComponent implements OnInit {
}
});
}
removePhoto() {
if (typeof document != 'undefined') {
(<HTMLInputElement>document.getElementById("photo")).value = "";
}
// this.initPhoto();
if (typeof document != 'undefined') {
(<HTMLInputElement>document.getElementById("photo")).value = "";
}
// this.initPhoto();
console.log(this.background.imageFile + " " + this.oldBackground.imageFile)
if(this.background.imageFile != this.oldBackground.imageFile){
this.deletePhoto();
}
this.background.imageFile = null;
this.file = null;
if (this.background.imageFile != this.oldBackground.imageFile) {
this.deletePhoto();
}
this.background.imageFile = null;
this.file = null;
}
public deletePhoto() {
if (this.background.imageFile) {
this.subscriptions.push(this.utilsService.deletePhoto(properties.utilsService + '/delete/community/' + this.communityId + "/" +this.background.imageFile).subscribe());
this.subscriptions.push(this.utilsService.deletePhoto(properties.utilsService + '/delete/community/' + this.communityId + "/" + this.background.imageFile).subscribe());
}
}
fileChangeEvent(event) {
if (event.target.files && event.target.files[0]) {
this.file = event.target.files[0];
@ -105,7 +109,7 @@ export class BackgroundUploadComponent implements OnInit {
});
this.removePhoto();
} else if (this.file.size > this.maxsize) {
UIkit.notification('File exceeds size\'s limit ('+this.maxsize/1024+'KB)! ', {
UIkit.notification('File exceeds size\'s limit (' + this.maxsize / 1024 + 'KB)! ', {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
@ -122,27 +126,34 @@ export class BackgroundUploadComponent implements OnInit {
}
}
}
public save() {
if (this.file) {
this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/community/"+ this.communityId + "/" + encodeURIComponent(this.communityId+"-"+this.label)+"?big=1", this.file).subscribe(res => {
this.subscriptions.push(this.utilsService.uploadPhoto(this.properties.utilsService + "/upload/community/" + this.communityId + "/" + encodeURIComponent(this.communityId + "-" + this.label) + "?big=1", this.file).subscribe(res => {
this.deletePhoto();
this.removePhoto();
this.background.imageFile = res.filename;
}, error => {
UIkit.notification("An error has been occurred during upload your image. Try again later", {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
if (error.error.message) {
UIkit.notification('The maximum size of an image is 1MB, please check if your file exceeds this limit.', {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
} else {
UIkit.notification("An error has been occurred during upload your image. Try again later", {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
}
}));
}
}
getUrl()
{
return "url('" +(this.background.imageFile.indexOf('data:')==-1?(this.properties.utilsService +
'/download/'+this.background.imageFile):this.background.imageFile) +"')";
getUrl() {
return "url('" + (this.background.imageFile.indexOf('data:') == -1 ? (this.properties.utilsService +
'/download/' + this.background.imageFile) : this.background.imageFile) + "')";
}
}

@ -6,10 +6,10 @@ import {Component, EventEmitter, Input, OnInit, Output,} from '@angular/core';
template: `
<div class="uk-grid ">
<div class="uk-margin-remove">
<div class="uk-text-bold uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta"> Border radius (px)
<a *ngIf="radius != radiusPublished" class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
(click)="radius = radiusPublished;borderChanged()"> <icon name="reset"></icon></a>
<div class="uk-text-bold uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-flex uk-flex-middle"> Border radius (px)
<a *ngIf="radius != radiusPublished" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
(click)="radius = radiusPublished;borderChanged()"> <icon name="settings_backup_restore" flex="true"></icon></a>
</div>
<div class="input-box">
@ -17,10 +17,10 @@ import {Component, EventEmitter, Input, OnInit, Output,} from '@angular/core';
</div>
</div>
<div class="uk-margin-small-top">
<div class="uk-text-bold uk-text-uppercase uk-text-meta uk-margin-xsmall-bottom"> Border width (px)
<a *ngIf="width != widthPublished" class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
(click)="width = widthPublished; borderChanged()"> <icon name="reset"></icon></a>
<div class="uk-text-bold uk-text-uppercase uk-text-meta uk-margin-xsmall-bottom uk-flex uk-flex-middle"> Border width (px)
<a *ngIf="width != widthPublished" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
(click)="width = widthPublished; borderChanged()"> <icon name="settings_backup_restore" flex="true"></icon></a>
</div>
<div class="input-box">
<div input inputClass="flat x-small" [(value)]="width" (valueChange)="borderChanged()" type="text" ></div>

@ -17,18 +17,18 @@ import {CustomizationOptions} from '../../openaireLibrary/connect/community/Cust
</div>
</div>
<div class="uk-text-warning uk-text-xsmall uk-margin-small-left" *ngIf="warningForContrast(color)">Contrast ratio may be too low.</div>
<div class="uk-text-warning uk-text-xsmall uk-margin-small-left" [class.uk-invisible]="!warningForContrast(color)">Contrast ratio may be too low.</div>
`,
styles:[
`
.color-input{
width:24px;
height:14px;
border-radius:3px;
border:0.1px solid #707070;
cursor: pointer;
}`
.color-input{
width:24px;
height:14px;
border-radius:3px;
border:0.1px solid #707070;
cursor: pointer;
}`
]
})

@ -1,141 +1,135 @@
<aside *ngIf="draftCustomizationOptions" id="sidebar_main">
<div id="sidebar_content">
<div class="menu_section uk-margin-large-top">
<a (click)="close()" class="uk-button uk-button-link uk-margin-left">
<h6 class="uk-margin-remove-bottom uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="draftCustomizationOptions" class="uk-flex">
<aside id="sidebar_main" class="uk-sticky" uk-sticky="start: 0; end: .sidebar_main_swipe">
<div sidebar-content>
<div class="back">
<a (click)="close()" class="uk-flex uk-flex-middle uk-flex-center">
<div class="uk-width-auto">
<icon *ngIf="menuSelected.id != 'home'" class="menu-icon" name="west" ratio="1.5"
<icon *ngIf="menuSelected.id != 'home'" name="west" ratio="1.3"
[flex]="true"></icon>
<icon *ngIf="menuSelected.id == 'home'" class="menu-icon" name="close" ratio="2"
<icon *ngIf="menuSelected.id == 'home'" name="close" ratio="1.3"
[flex]="true"></icon>
</div>
<span class="uk-width-expand uk-text-truncate uk-margin-small-left">{{menuSelected.name}}</span>
</h6>
</a>
</div>
<div class="menu_section uk-margin-large-top uk-overflow-auto" style="max-height: 75vh">
<ul *ngIf="menuSelected.id == 'home'" class="uk-list uk-nav uk-nav-default" uk-nav>
<ng-template ngFor [ngForOf]="sidebarItems" let-item let-i="index">
<li class="uk-visible-toggle" [class.uk-active]="menuSelected.id == item.id">
<a (click)="changeMenu(item)"
[title]="item.name">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="item.icon" class="uk-width-auto">
<icon class="menu-icon" [name]="item.icon" [flex]="true"></icon>
</div>
<span
class="uk-width-expand uk-text-truncate uk-margin-small-left">
<span class="uk-width-expand uk-text-truncate uk-margin-left hide-on-close">{{menuSelected.name}}</span>
</a>
</div>
<div class="menu_section uk-margin-large-top">
<ul *ngIf="menuSelected.id == 'home'" class="uk-list uk-nav uk-nav-default" uk-nav>
<ng-template ngFor [ngForOf]="sidebarItems" let-item let-i="index">
<li class="uk-visible-toggle" [class.uk-active]="menuSelected.id == item.id">
<a (click)="changeMenu(item)"
[title]="item.name">
<div class="uk-flex uk-flex-middle uk-flex-center">
<div *ngIf="item.icon" class="uk-width-auto">
<icon class="menu-icon" [name]="item.icon" [flex]="true"></icon>
</div>
<span class="uk-width-expand uk-text-truncate uk-margin-small-left hide-on-close">
{{item.name}}
</span>
<span uk-icon="triangle-right"></span>
</div>
</a>
</li>
</ng-template>
</ul>
<ng-container *ngIf="menuSelected.id == 'identity'">
<ng-container
*ngTemplateOutlet="identityOptions ; context: { }"></ng-container>
</ng-container>
<ng-container *ngIf="menuSelected.id == 'backgrounds'">
<ng-container
*ngTemplateOutlet="backgroundOptions ; context: { }"></ng-container>
</ng-container>
<ng-container *ngIf="menuSelected.id == 'buttons'">
<ng-container
*ngTemplateOutlet="buttonOptions ; context: { }"></ng-container>
</ng-container>
<span uk-icon="triangle-right"></span>
</div>
</a>
</li>
</ng-template>
</ul>
<ng-container *ngIf="menuSelected.id == 'identity'">
<ng-container
*ngTemplateOutlet="identityOptions ; context: { }"></ng-container>
</ng-container>
<ng-container *ngIf="menuSelected.id == 'backgrounds'">
<ng-container
*ngTemplateOutlet="backgroundOptions ; context: { }"></ng-container>
</ng-container>
<ng-container *ngIf="menuSelected.id == 'buttons'">
<ng-container
*ngTemplateOutlet="buttonOptions ; context: { }"></ng-container>
</ng-container>
</div>
</div>
</div>
</aside>
<div *ngIf="draftCustomizationOptions" page-content>
<div actions>
<div class="uk-section-small">
<ng-container *ngTemplateOutlet="applyResetButtons;"></ng-container>
</aside>
<div page-content class="uk-width-1-1">
<div actions>
<div class="uk-section-small">
<ng-container *ngTemplateOutlet="applyResetButtons;"></ng-container>
</div>
</div>
</div>
<div inner>
<div class="uk-section-small">
<div *ngIf="menuSelected.id == 'backgrounds'" class=" uk-padding-small ">
<div class="customizationMenuItems uk-margin-small">
<div class="uk-h4">Backgrounds</div>
<div>Note: Custom background style settings will override any identity settings that effect the
visualisation of a background.
</div>
<div inner>
<div class="uk-section-small">
<div *ngIf="menuSelected.id == 'backgrounds'" class=" uk-padding-small ">
<div class="customizationMenuItems uk-margin-small">
<div class="uk-h4">Backgrounds</div>
<div>Note: Custom background style settings will override any identity settings that effect the
visualisation of a background.
</div>
<div class="uk-margin-large-top uk-margin-small-bottom uk-h5"> Quick look
<div class="uk-margin-large-top uk-margin-small-bottom uk-h5"> Quick look
</div>
<quick-look-backgrounds [darkBackgroundColor]="draftCustomizationOptions.backgrounds.dark.color "
[lightBackgroundColor]="draftCustomizationOptions.backgrounds.light.color "
[formBackgroundColor]="draftCustomizationOptions.backgrounds.form.color"
[primaryColor]="draftCustomizationOptions.identity.mainColor"
[secondaryColor]="draftCustomizationOptions.identity.secondaryColor"
[buttonsOnDark]="draftCustomizationOptions.buttons.darkBackground"
[buttonsOnLight]="draftCustomizationOptions.buttons.lightBackground"
></quick-look-backgrounds>
</div>
<quick-look-backgrounds [darkBackgroundColor]="draftCustomizationOptions.backgrounds.dark.color "
[lightBackgroundColor]="draftCustomizationOptions.backgrounds.light.color "
[formBackgroundColor]="draftCustomizationOptions.backgrounds.form.color"
[primaryColor]="draftCustomizationOptions.identity.mainColor"
[secondaryColor]="draftCustomizationOptions.identity.secondaryColor"
[buttonsOnDark]="draftCustomizationOptions.buttons.darkBackground"
[buttonsOnLight]="draftCustomizationOptions.buttons.lightBackground"
></quick-look-backgrounds>
</div>
</div>
<div *ngIf="menuSelected.id == 'buttons'" class=" uk-padding-small ">
<div class="customizationMenuItems uk-margin-small">
<div class="uk-h4">Buttons</div>
<div>Note: Custom background style settings will override any identity settings that effect the
visualisation of a background.
</div>
</div>
<div *ngIf="menuSelected.id == 'buttons'" class=" uk-padding-small ">
<div class="customizationMenuItems uk-margin-small">
<div class="uk-h4">Buttons</div>
<div>Note: Custom background style settings will override any identity settings that effect the
visualisation of a background.
</div>
<div class="uk-margin-large-top uk-margin-small-bottom uk-h5"> Quick look
<div class="uk-margin-large-top uk-margin-small-bottom uk-h5"> Quick look
</div>
<quick-look-backgrounds [darkBackgroundColor]="draftCustomizationOptions.backgrounds.dark.color "
[lightBackgroundColor]="draftCustomizationOptions.backgrounds.light.color "
[formBackgroundColor]="draftCustomizationOptions.backgrounds.form.color"
[primaryColor]="draftCustomizationOptions.identity.mainColor"
[secondaryColor]="draftCustomizationOptions.identity.secondaryColor"
[buttonsOnDark]="draftCustomizationOptions.buttons.darkBackground"
[buttonsOnLight]="draftCustomizationOptions.buttons.lightBackground"
[buttonView]="true"
></quick-look-backgrounds>
</div>
<quick-look-backgrounds [darkBackgroundColor]="draftCustomizationOptions.backgrounds.dark.color "
[lightBackgroundColor]="draftCustomizationOptions.backgrounds.light.color "
[formBackgroundColor]="draftCustomizationOptions.backgrounds.form.color"
[primaryColor]="draftCustomizationOptions.identity.mainColor"
[secondaryColor]="draftCustomizationOptions.identity.secondaryColor"
[buttonsOnDark]="draftCustomizationOptions.buttons.darkBackground"
[buttonsOnLight]="draftCustomizationOptions.buttons.lightBackground"
[buttonView]="true"
></quick-look-backgrounds>
</div>
<div *ngIf="menuSelected.id == 'identity'" class=" uk-padding-small ">
<div class=" customizationMenuItems uk-margin-small">
</div>
<div *ngIf="menuSelected.id == 'identity'" class=" uk-padding-small ">
<div class=" customizationMenuItems uk-margin-small">
<div class="uk-h4">Identity</div>
<div>Note: Custom identity style settings will effect the visualisation of the whole gateway. That
includes <span class="uk-text-bold">buttons, links, tabs, backgrounds, etc.</span></div>
<div class="uk-h4">Identity</div>
<div>Note: Custom identity style settings will effect the visualisation of the whole gateway. That
includes <span class="uk-text-bold">buttons, links, tabs, backgrounds, etc.</span></div>
</div>
</div>
</div>
<div class="uk-padding-small">
<div class="uk-margin-top uk-margin-small-bottom uk-h5">See a preview</div>
<div id="container" class=" uk-flex uk-flex-center uk-flex-middle">
<div id="iframecontainer" class="">
<div class="uk-height-1-1">
<div *ngIf="hasChanges(draftCustomizationOptions, appliedCustomizationOptions)"
class=" uk-width-1-1 refresh-indicator">
<div class="uk-position-relative uk-height-1-1">
<div class="uk-position-center uk-text-center clickable uk-h3" style="color:white"
(click)="applyLayout()">
<div>
<icon name="refresh" ratio="2.5"></icon>
<div class="uk-padding-small">
<div class="uk-margin-top uk-margin-small-bottom uk-h5">See a preview</div>
<div id="container" class=" uk-flex uk-flex-center uk-flex-middle">
<div id="iframecontainer" class="">
<div class="uk-height-1-1">
<div *ngIf="hasChanges(draftCustomizationOptions, appliedCustomizationOptions)"
class=" uk-width-1-1 refresh-indicator">
<div class="uk-position-relative uk-height-1-1">
<div class="uk-position-center uk-text-center clickable uk-h3" style="color:white"
(click)="applyLayout()">
<div>
<icon name="refresh" ratio="2.5"></icon>
</div>
<div class="uk-margin-medium-top">Style has been changed.</div>
<div class="uk-margin-top"> Click to refresh the view.</div>
</div>
<div class="uk-margin-medium-top">Style has been changed.</div>
<div class="uk-margin-top"> Click to refresh the view.</div>
</div>
</div>
</div>
<iframe *ngIf="previewUrl" [src]="previewUrl" class="uk-width-1-1 "
style=" border-radius: 10px;"
></iframe>
<iframe *ngIf="previewUrl" [src]="previewUrl" class="uk-width-1-1 "
style=" border-radius: 10px;"
></iframe>
</div>
</div>
</div>
</div>
@ -143,6 +137,7 @@
</div>
</div>
</div>
<ng-template #identityOptions>
<div class="functionalities-container uk-text-small">
<div class="uk-margin-top">
@ -153,20 +148,20 @@
(change)="draftCustomizationOptions.identityIsCustom =
!draftCustomizationOptions.identityIsCustom;
draftCustomizationOptions.identityIsCustom?'':this.resetIdentityToDefault();"
[attr.uk-tooltip]="'title:<div class=\'uk-padding-small uk-width-large\'>' +
[attr.uk-tooltip]="'title:<div class=\'uk-width-large\'>' +
(draftCustomizationOptions.identityIsCustom?'Change to default identity values':'Customize identity colors')+'</div>'"
>
</mat-slide-toggle>
</div>
</div>
<div *ngIf="draftCustomizationOptions.identityIsCustom" class=" uk-margin-large-top uk-margin-medium-bottom">
<div class=" uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold">
<div class=" uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-flex uk-flex-middle">
Colors
<a *ngIf="hasChanges(publishedCustomizationOptions.identity, draftCustomizationOptions.identity) &&
draftCustomizationOptions.identityIsCustom" class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
draftCustomizationOptions.identityIsCustom" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
(click)="resetIdentityToPublished();">
<icon name="reset"></icon>
<icon name="settings_backup_restore" flex="true"></icon>
</a>
</div>
<color [color]="draftCustomizationOptions.identity.mainColor" [light]="false" (colorChange)=
@ -187,7 +182,7 @@
[checked]="draftCustomizationOptions.backgroundsIsCustom"
(change)="draftCustomizationOptions.backgroundsIsCustom=!draftCustomizationOptions.backgroundsIsCustom;
draftCustomizationOptions.backgroundsIsCustom?'':this.resetBackgroundsToDefault(); "
[attr.uk-tooltip]="'title:<div class=\'uk-padding-small uk-width-large\'>' +
[attr.uk-tooltip]="'title:<div class=\'uk-width-large\'>' +
(draftCustomizationOptions.backgroundsIsCustom?'Change to default values produced based on the identity colors':'Customize options for background and buttons')+'</div>'"
>
</mat-slide-toggle>
@ -195,7 +190,7 @@
</div>
<div *ngIf="draftCustomizationOptions.backgroundsIsCustom" >
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-large-top">
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-large-top uk-flex uk-flex-middle">
Colors
<a *ngIf="(
hasChanges(publishedCustomizationOptions.backgrounds.light, draftCustomizationOptions.backgrounds.light)||
@ -203,10 +198,10 @@
hasChanges(publishedCustomizationOptions.backgrounds.form.color, draftCustomizationOptions.backgrounds.form.color))
&& draftCustomizationOptions.backgroundsIsCustom"
(click)="resetBackgroundsTo(publishedCustomizationOptions.backgrounds);"
class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
>
<icon name="reset"></icon>
<icon name="settings_backup_restore" flex="true"></icon>
</a>
</div>
<background label="Dark" [background]="draftCustomizationOptions.backgrounds.dark"
@ -214,23 +209,46 @@
<background label="Light" [background]="draftCustomizationOptions.backgrounds.light"
[light]="true"></background>
<background label="Hero section" [background]="draftCustomizationOptions.backgrounds.form"
[light]="true"
[light]="draftCustomizationOptions.backgrounds.form.fontsDarkMode"
[oldBackground]="publishedCustomizationOptions.backgrounds.form"
[communityId]="communityId" description="The area under menu"></background>
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-large-top">
Hero section image
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-large-top uk-flex uk-flex-middle uk-heading-divider">
Hero section
</div>
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-medium-top uk-flex uk-flex-middle">
Fonts
<a *ngIf="( publishedCustomizationOptions.backgrounds.form.fontsDarkMode != draftCustomizationOptions.backgrounds.form.fontsDarkMode )
&& draftCustomizationOptions.backgroundsIsCustom"
(click)="draftCustomizationOptions.backgrounds.form.fontsDarkMode=publishedCustomizationOptions.backgrounds.form.fontsDarkMode;" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>">
<icon name="settings_backup_restore" flex="true"></icon>
</a>
</div>
<div class="uk-margin-small-top">
<span>Dark mode </span>
<span>
<mat-slide-toggle class="uk-margin-large-left"
[checked]="draftCustomizationOptions.backgrounds.form.fontsDarkMode"
(change)="draftCustomizationOptions.backgrounds.form.fontsDarkMode=!draftCustomizationOptions.backgrounds.form.fontsDarkMode;"
[attr.uk-tooltip]="'title:<div class=\'uk-width-large\'>' +
(draftCustomizationOptions.backgrounds.form.fontsDarkMode?'Change to light color mode if the hero section background is dark':'Change to dark mode if the hero section background is light')+'</div>'"
>
</mat-slide-toggle>
</span>
</div>
<div class="uk-margin-xsmall-bottom uk-text-uppercase uk-text-meta uk-text-bold uk-margin-medium-top uk-flex uk-flex-middle">
Image
<a *ngIf="(formHasChanges(publishedCustomizationOptions, draftCustomizationOptions) )
&& draftCustomizationOptions.backgroundsIsCustom"
(click)="resetImageTo(publishedCustomizationOptions.backgrounds);" class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
>
<icon name="reset"></icon>
(click)="resetImageTo(publishedCustomizationOptions.backgrounds);" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>">
<icon name="settings_backup_restore" flex="true"></icon>
</a>
</div>
<div class="uk-margin-medium-bottom">
<background-upload label="Form" [background]="draftCustomizationOptions.backgrounds.form"
[oldBackground]="publishedCustomizationOptions.backgrounds.form"
[communityId]="communityId"></background-upload>
[communityId]="communityId" [light]="draftCustomizationOptions.backgrounds.form.fontsDarkMode" ></background-upload>
</div>
</div>
</div>
@ -245,7 +263,7 @@
[checked]="draftCustomizationOptions.buttonsIsCustom"
(change)="draftCustomizationOptions.buttonsIsCustom=!draftCustomizationOptions.buttonsIsCustom;
draftCustomizationOptions.buttonsIsCustom?'':this.resetButtonsToDefault(); "
[attr.uk-tooltip]="'title:<div class=\'uk-padding-small uk-width-large\'>' +
[attr.uk-tooltip]="'title:<div class=\'uk-width-large\'>' +
(draftCustomizationOptions.buttonsIsCustom?'Change to default values produced based on the identity colors':'Customize options for background and buttons')+'</div>'"
>
</mat-slide-toggle>

@ -22,7 +22,6 @@ import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import {CustomizeButtonsComponent} from './customize-buttons.component';
import {IconsModule} from '../../openaireLibrary/utils/icons/icons.module';
import {IconsService} from '../../openaireLibrary/utils/icons/icons.service';
import {refresh, reset} from '../../openaireLibrary/utils/icons/icons';
import {BackgroundComponent} from './background.component';
import {InputModule} from '../../openaireLibrary/sharedComponents/input/input.module';
import {BackgroundUploadComponent} from "./background-upload.component";
@ -44,7 +43,5 @@ import {SideBarModule} from "../../openaireLibrary/dashboard/sharedComponents/si
]
})
export class CustomizationModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([reset, refresh]);
}
constructor() {}
}

@ -21,10 +21,10 @@ import {ButtonsCustomization} from '../../openaireLibrary/connect/community/Cust
</div>
<div *ngIf="!onlyBorder" class="uk-grid uk-margin-top" >
<div class="">
<div class=" uk-margin-xsmall-bottom uk-text-bold uk-margin-small-left uk-text-meta uk-text-uppercase">Colors
<a *ngIf="buttons.color !=buttonsPublished.color || buttons.backgroundColor != buttonsPublished.backgroundColor || buttons.borderColor !=buttonsPublished.borderColor " class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
(click)="buttons.color =buttonsPublished.color; buttons.backgroundColor = buttonsPublished.backgroundColor ; buttons.borderColor =buttonsPublished.borderColor "> <icon name="reset"></icon></a>
<div class=" uk-margin-xsmall-bottom uk-text-bold uk-margin-small-left uk-text-meta uk-text-uppercase uk-flex uk-flex-middle">Colors
<a *ngIf="buttons.color !=buttonsPublished.color || buttons.backgroundColor != buttonsPublished.backgroundColor || buttons.borderColor !=buttonsPublished.borderColor " class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
(click)="buttons.color =buttonsPublished.color; buttons.backgroundColor = buttonsPublished.backgroundColor ; buttons.borderColor =buttonsPublished.borderColor "> <icon name="settings_backup_restore" flex="true"></icon></a>
</div>
<color [color]="buttons.color" (colorChange)=
" buttons.color = $event; "
@ -40,11 +40,11 @@ import {ButtonsCustomization} from '../../openaireLibrary/connect/community/Cust
></color>
</div>
<div class="uk-margin-top">
<div class=" uk-margin-xsmall-bottom uk-text-bold uk-margin-small-left uk-text-meta uk-text-uppercase">Colors on hover
<a *ngIf="hasChanges(buttons.onHover,buttonsPublished.onHover)" class="uk-margin-small-left"
uk-tooltip="title:<div class='uk-padding-small uk-width-large'>Reset to previously saved options</div>"
<div class=" uk-margin-xsmall-bottom uk-text-bold uk-margin-small-left uk-text-meta uk-text-uppercase uk-flex uk-flex-middle">Colors on hover
<a *ngIf="hasChanges(buttons.onHover,buttonsPublished.onHover)" class="uk-margin-small-left uk-button-link"
uk-tooltip="title:<div class='uk-width-large'>Reset to previously saved options</div>"
(click)="buttons.onHover.color =buttonsPublished.onHover.color; buttons.onHover.backgroundColor = buttonsPublished.onHover.backgroundColor ;
buttons.onHover.borderColor = buttonsPublished.onHover.borderColor"> <icon name="reset"></icon></a>
buttons.onHover.borderColor = buttonsPublished.onHover.borderColor"> <icon name="settings_backup_restore" flex="true"></icon></a>
</div>
<div class="">
<color [color]="buttons.onHover.color" (colorChange)=

@ -20,14 +20,6 @@ type Tab = 'all' | 'communities' | 'ris';
template: `
<div page-content [id]="tab">
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">
Admin Dashboard - Manage Communities
</div>
<h1 class="uk-h6 uk-margin-remove">Research Communities & Initiatives</h1>
</div>
</div>
<ul class="uk-tab uk-margin-medium-top" uk-tab>
<li [class.uk-active]="tab === 'all'"><a (click)="tab = 'all'"><span class="title">All</span></a></li>
<li [class.uk-active]="tab === 'communities'"><a (click)="tab = 'communities'"><span class="title">Research Communities</span></a>
@ -91,7 +83,7 @@ type Tab = 'all' | 'communities' | 'ris';
<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">
<div class="uk-flex uk-flex-middle">
<icon [flex]="true" [name]="community.status == 'all'?'earth':(community.status == 'manager'?'restricted':'incognito')" ratio="0.6"></icon>
<icon [flex]="true" [name]="community.isPublic()?'earth':(community.isRestricted()?'restricted':'incognito')" ratio="0.6"></icon>
</div>
</div>
<a class="uk-display-block uk-text-center uk-link-reset" [routerLink]="community.communityId">

@ -10,7 +10,7 @@ import {UrlPrefixModule} from '../../openaireLibrary/utils/pipes/url-prefix.modu
import {CommunitiesService} from '../../openaireLibrary/connect/communities/communities.service';
import {IconsModule} from '../../openaireLibrary/utils/icons/icons.module';
import {IconsService} from '../../openaireLibrary/utils/icons/icons.service';
import {earth, group, lock} from '../../openaireLibrary/utils/icons/icons';
import {earth, incognito, restricted} from '../../openaireLibrary/utils/icons/icons';
import {LogoUrlPipeModule} from "../../openaireLibrary/utils/pipes/logoUrlPipe.module";
import {SearchInputModule} from '../../openaireLibrary/sharedComponents/search-input/search-input.module';
@ -24,6 +24,6 @@ import {SearchInputModule} from '../../openaireLibrary/sharedComponents/search-i
})
export class ManageCommunitiesModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([earth]);
this.iconsService.registerIcons([earth, restricted, incognito]);
}
}

@ -94,12 +94,12 @@
<div class="uk-card-body">
<result-preview [properties]="properties" [showOrganizations]="true"
[showSubjects]="true" [result]="getResultPreview(result)"
[externalUrl]="projectUrl">
[externalUrl]="projectUrl" [hasLink]="false">
</result-preview>
</div>
<div class="uk-card-footer uk-padding-remove-vertical">
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<div *ngIf="!getCommunityProject(result)">
<div *ngIf="!result['isPart']">
<div class="uk-padding-small uk-padding-remove-horizontal">
<a (click)="addProject(result)" class="uk-button uk-button-link uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
@ -109,7 +109,7 @@
</a>
</div>
</div>
<div *ngIf="getCommunityProject(result)">
<div *ngIf="result['isPart']">
<div class="uk-padding-small uk-padding-remove-horizontal">
<a (click)="removeProject(result)"
class="uk-button uk-button-link uk-flex uk-flex-middle">

@ -19,6 +19,7 @@ import {CommunityInfo} from "../../openaireLibrary/connect/community/communityIn
import {OpenaireEntities} from "../../openaireLibrary/utils/properties/searchFields";
import {Filter, Value} from "../../openaireLibrary/searchPages/searchUtils/searchHelperClasses.class";
import {ClearCacheService} from "../../openaireLibrary/services/clear-cache.service";
import {SearchCommunityProjectsService} from "../../openaireLibrary/connect/projects/searchProjects.service";
declare var UIkit;
@ -38,7 +39,7 @@ export class AddProjectsComponent implements OnInit {
public errorCodes: ErrorCodes;
public openaireSearchUtils: SearchUtilsClass = new SearchUtilsClass();
@Output() communityProjectsChanged = new EventEmitter();
@Input() communityProjects = [];
// @Input() communityProjects = [];
public openaireProjects = [];
public queryParameters: string = "";
@ -58,7 +59,7 @@ export class AddProjectsComponent implements OnInit {
constructor(private route: ActivatedRoute, private _router: Router, private _searchProjectsService: SearchProjectsService,
private _manageCommunityProjectsService: ManageCommunityProjectsService,
private _clearCacheService: ClearCacheService,
private _clearCacheService: ClearCacheService, private _searchCommunityProjectsService: SearchCommunityProjectsService,
private _fb: UntypedFormBuilder) {
this.errorCodes = new ErrorCodes();
this.openaireSearchUtils.status = this.errorCodes.LOADING;
@ -121,15 +122,17 @@ export class AddProjectsComponent implements OnInit {
public addProject(project: SearchResult) {
this.subscriptions.push(this._manageCommunityProjectsService.addProject(this.properties, this.community.communityId, project).subscribe(
data => {
this.communityProjects.push(data);
// this.communityProjects.push(data);
this._clearCacheService.purgeBrowserCache(this.openaireEntities.PROJECT+" added", this.community.communityId);
UIkit.notification(this.openaireEntities.PROJECT+' successfully added!', {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
project["isPart"] = true;
this.communityProjectsChanged.emit({
value: this.communityProjects,
value: project,
});
},
err => {
@ -140,20 +143,20 @@ export class AddProjectsComponent implements OnInit {
}
public removeProject(project: any) {
let communityProject = this.getCommunityProject(project);
let projectId: string = communityProject['id'];
this.subscriptions.push(this._manageCommunityProjectsService.removeProject(this.properties, this.community.communityId, projectId).subscribe(
// let communityProject = this.getCommunityProject(project);
this.subscriptions.push(this._manageCommunityProjectsService.removeProject(this.properties, this.community.communityId, project['id']).subscribe(
data => {
let index = this.communityProjects.indexOf(communityProject);
this.communityProjects.splice(index, 1);
// let index = this.communityProjects.indexOf(communityProject);
// this.communityProjects.splice(index, 1);
this._clearCacheService.purgeBrowserCache(this.openaireEntities.PROJECT+" removed", this.community.communityId);
UIkit.notification(this.openaireEntities.PROJECT+' successfully removed!', {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
project["isPart"] = false;
this.communityProjectsChanged.emit({
value: this.communityProjects,
value: project,
});
},
err => {
@ -163,16 +166,19 @@ export class AddProjectsComponent implements OnInit {
));
}
public getCommunityProject(project: any): string {
let index: number = 0;
for (let communityProject of this.communityProjects) {
if (communityProject.openaireId == project.id ||
(project.code == communityProject.grantId && project.funderShortname == communityProject.funder)) {
return communityProject;
public getCommunityProject(project: any) {
this.subscriptions.push(this._searchCommunityProjectsService.searchProjectsWithPaging(this.properties, this.community.communityId, 1, this.resultsPerPage, project.id, null).subscribe(
data => {
if(data.totalElements > 0){
project["isPart"] = true;
}
},
err => {
console.error(err);
//TODO check erros (service not available, bad request)
}
index++;
}
return "";
));
}
getFunders() {
@ -217,7 +223,9 @@ export class AddProjectsComponent implements OnInit {
data => {
this.openaireSearchUtils.totalResults = data[0];
this.openaireProjects = data[1];
for(let project of this.openaireProjects){
this.getCommunityProject(project);
}
this.openaireSearchUtils.status = this.errorCodes.DONE;
if (this.openaireSearchUtils.totalResults == 0) {
this.openaireSearchUtils.status = this.errorCodes.NONE;

@ -14,7 +14,6 @@ import {SearchPagingModule} from '../../openaireLibrary/searchPages/searchUtils/
import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.module';
import {CommonModule} from '@angular/common';
import {PageContentModule} from "../../openaireLibrary/dashboard/sharedComponents/page-content/page-content.module";
import {CommunityInfoModule} from "../community-info/community-info.module";
import {InputModule} from "../../openaireLibrary/sharedComponents/input/input.module";
import {SearchInputModule} from "../../openaireLibrary/sharedComponents/search-input/search-input.module";
import {NoLoadPaging} from "../../openaireLibrary/searchPages/searchUtils/no-load-paging.module";
@ -38,7 +37,6 @@ import {SearchFilterModule} from "../../openaireLibrary/searchPages/searchUtils/
AlertModalModule,
SearchProjectsServiceModule,
PageContentModule,
CommunityInfoModule,
InputModule,
SearchInputModule,
RouterModule.forChild([

@ -16,12 +16,11 @@ import {CommunityService} from "../../openaireLibrary/connect/community/communit
@Component({
selector: 'manage-projects',
template: `
<remove-projects #removeProjectsComponent (addProjects)="openAddProjects()" [communityProjects]="communityProjects"
[loading]="showLoadingInRemove" [community]="community"
(communityProjectsChanged)="communityProjectsChanged($event)">
<remove-projects #removeProjectsComponent (addProjects)="openAddProjects()"
[loading]="showLoadingInRemove" [community]="community">
</remove-projects>
<fs-modal #fsModalProjects>
<add-projects #addProjects [communityProjects]="communityProjects" [community]="community"
<add-projects *ngIf="modalIsOpen" #addProjects [community]="community"
(communityProjectsChanged)="communityProjectsChanged($event)"></add-projects>
</fs-modal>
`
@ -36,6 +35,7 @@ export class ManageProjectsComponent implements OnInit {
public body: string = "Send from page";
public properties: EnvProperties = properties;
public community: CommunityInfo = null;
modalIsOpen = false;
constructor(private element: ElementRef,
private title: Title,
@ -68,15 +68,17 @@ export class ManageProjectsComponent implements OnInit {
this.fullscreen.back = true;
this.fullscreen.okButton = true;
this.fullscreen.open();
this.modalIsOpen = true;
}
public communityProjectsChanged($event) {
this.communityProjects = $event.value;
/* this.communityProjects = $event.value;
this.showLoadingInRemove = false;
if (this.fullscreen.isOpen) {
this.removeProjectsComponent.applyFilters();
this.removeProjectsComponent.createFunderFilter();
}
}*/
this.removeProjectsComponent.getCommunityProjects();
}
}

@ -1,16 +1,6 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage {{openaireEntiites.PROJECTS}}
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="projects"></community-info>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-middle">
<div class="uk-width-expand@m uk-width-1-1 uk-grid uk-flex-middle uk-flex-right@m uk-flex-center uk-margin-remove-left" uk-grid>
<div search-input [expandable]="true" [searchControl]="filterForm.get('keyword')" searchInputClass="outer"
@ -34,20 +24,21 @@
</div>
<div inner>
<div class="uk-margin-top">
<results-and-pages [type]="openaireEntiites.PROJECTS | lowercase" [page]="page" [pageSize]="resultsPerPage"
[totalResults]="previewCommunityProjects.length"></results-and-pages>
<results-and-pages [type]="openaireEntiites.PROJECTS | lowercase" [page]="communitySearchUtils.page" [pageSize]="resultsPerPage"
[totalResults]="communitySearchUtils.totalResults"></results-and-pages>
</div>
<div class="uk-grid uk-flex-middle uk-margin-medium-top" uk-grid>
<div *ngIf="allOptions.length > 0">
<div *ngIf="allFunderOptions.length > 0">
<dropdown-filter #dropdownFilter dropdownClass="uk-width-medium uk-padding-small"
name="Filter by Funder" [count]="filterForm.get('funder').value.length">
name="Filter by Funder" [count]="filterForm.get('funder').value?1:null">
<h6 class="uk-margin-remove-bottom" title="Filter by Funder">Funder</h6>
<ul class="uk-list uk-margin-remove-bottom">
<li *ngFor="let option of allOptions">
<a class="uk-link-text">
<label (click)="select(option.value, $event, dropdownFilter)" class="uk-flex uk-flex-middle">
<li *ngFor="let option of previewFunderOptions">
<a class="uk-link-text" >
<label (click)="select(option, $event, dropdownFilter)" class="uk-flex uk-flex-middle">
<input class="uk-checkbox"
type="checkbox" [checked]="isSelected(option.value)">
type="checkbox" [checked]="isSelected(option.value.id)">
<span class="uk-margin-small-left">{{option.label}}</span>
</label>
</a>
@ -65,9 +56,9 @@
</div>
<!-- </div>-->
<div class="uk-width-expand@l uk-width-1-1 uk-flex uk-flex-right@m uk-flex-center">
<paging-no-load *ngIf="previewCommunityProjects.length > 0"
<paging-no-load *ngIf="communitySearchUtils.totalResults> 0" [currentPage]="communitySearchUtils.page"
(pageChange)="updatePage($event)" [size]="resultsPerPage"
[totalResults]="previewCommunityProjects.length" customClasses="uk-flex-right">
[totalResults]="communitySearchUtils.totalResults" customClasses="uk-flex-right">
</paging-no-load>
</div>
</div>
@ -77,29 +68,28 @@
<loading></loading>
</div>
<div *ngIf="!loading">
<div class="uk-margin-medium-bottom">
<div *ngIf="previewCommunityProjects.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No {{openaireEntiites.PROJECTS | lowercase}}
<span *ngIf="communityProjects.length == 0; else: notFound">for {{community.shortTitle}}</span>
<span *ngIf="communitySearchUtils.totalResults == 0; else: notFound">for {{community.shortTitle}}</span>
<ng-template #notFound>found</ng-template>
</div>
</div>
<div *ngIf="previewCommunityProjects.length > 0"
class="uk-grid uk-grid-large uk-child-width-1-1 uk-child-width-1-2@m uk-margin-bottom" uk-grid uk-height-match="target: .uk-card-body">
<div *ngFor="let item of previewCommunityProjects.slice((page - 1)*resultsPerPage, page*resultsPerPage); let i=index">
<div *ngFor="let item of previewCommunityProjects; let i=index">
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<h6 class="uk-margin-bottom">
<a *ngIf="item.openaireId || (item.grantId && item.funder)"
<a *ngIf="(item.openaireId || (item.grantId && item.funder)) && (!item['availableSince'] || !lastDBLoadDate || item['availableSince']<lastDBLoadDate)"
target="_blank" class="custom-external uk-link-text"
[href]="projectUrl+'?' + ((item.openaireId) ? 'projectId='+item.openaireId : 'grantId='+item.grantId+'&funder='+item.funder)">
<span *ngIf="item.name">{{item.name}}</span>
<span *ngIf="item.name && item.acronym"> (</span><span *ngIf="item.acronym">{{item.acronym}}</span><span *ngIf="item.name && item.acronym">)</span>
<span *ngIf="!item.name && !item.acronym">[no title available]</span>
</a>
<span *ngIf="!item.openaireId && !(item.grantId && item.funder)">
<span *ngIf="(!item.openaireId && !(item.grantId && item.funder) || (item['availableSince'] && lastDBLoadDate && item['availableSince'] >= lastDBLoadDate))">
<span *ngIf="item.name">{{item.name}}</span>
<span *ngIf="item.name && item.acronym"> (</span><span *ngIf="item.acronym">{{item.acronym}}</span><span *ngIf="item.name && item.acronym">)</span>
<span *ngIf="!item.name && !item.acronym">[no title available]</span>
@ -134,7 +124,7 @@
</div>
<div class="uk-margin-small-top">
<paging-no-load [currentPage]="page"
[totalResults]="previewCommunityProjects.length" [size]="resultsPerPage"
[totalResults]="communitySearchUtils.totalResults" [size]="resultsPerPage"
(pageChange)="updatePage($event)" customClasses="uk-flex-right@m uk-flex-center">
</paging-no-load>
</div>

@ -19,6 +19,8 @@ import {CommunityInfo} from "../../openaireLibrary/connect/community/communityIn
import {HelperFunctions} from "../../openaireLibrary/utils/HelperFunctions.class";
import {NotificationHandler} from "../../openaireLibrary/utils/notification-handler";
import {ClearCacheService} from "../../openaireLibrary/services/clear-cache.service";
import {debounceTime, distinctUntilChanged} from "rxjs/operators";
import {IndexInfoService} from "../../openaireLibrary/utils/indexInfo.service";
@Component({
selector: 'remove-projects',
@ -35,7 +37,7 @@ export class RemoveProjectsComponent implements OnInit {
public projectUrl = "https://" + ((properties.environment == "beta" || properties.environment == "development") ? "beta." : "") + "explore.openaire.eu" + properties.searchLinkToProject.split("?")[0];
@Output() communityProjectsChanged = new EventEmitter();
@Input() public communityProjects = [];
// @Input() public communityProjects = [];
public previewCommunityProjects = [];
public communitySearchUtils: SearchUtilsClass = new SearchUtilsClass();
public errorCodes: ErrorCodes;
@ -51,56 +53,49 @@ export class RemoveProjectsComponent implements OnInit {
/* Search */
@ViewChild('searchInputComponent') searchInputComponent: SearchInputComponent;
filterForm: UntypedFormGroup;
public fundersCtrl: UntypedFormArray;
private searchText: RegExp = new RegExp('');
public keyword: string = '';
selectedFunders: string[] = [];
allOptions: Option[] = [];
allFunderOptions: Option[] = [];
previewFunderOptions: Option[] = [];
sortOptions: Option[] = [
//{label:"Title (desc) ", value:{ sort: "title",descending: true }},
{label: "Title ", value: {sort: "title", descending: false}},
//{label:"Grant ID (desc) ", value:{ sort: "grant",descending: true }},
{label: "Grant ID ", value: {sort: "grant", descending: false}},
//{label:"Funder (desc) ", value:{ sort: "funder",descending: true }},
{label: "Title ", value: {sort: "name", descending: false}},
{label: "Grant ID ", value: {sort: "grantId", descending: false}},
{label: "Funder ", value: {sort: "funder", descending: false}}
];
public openaireEntiites = OpenaireEntities;
lastDBLoadDate = null;
constructor(private route: ActivatedRoute, private _router: Router,
private _fb: UntypedFormBuilder,
private communityService: CommunityService,
private _manageCommunityProjectsService: ManageCommunityProjectsService,
private _searchCommunityProjectsService: SearchCommunityProjectsService,
private _clearCacheService: ClearCacheService) {
private _clearCacheService: ClearCacheService, private indexInfoService: IndexInfoService) {
this.errorCodes = new ErrorCodes();
this.communitySearchUtils.status = this.errorCodes.LOADING;
}
ngOnInit() {
this.subscriptions.push(this.indexInfoService.getDBLoadLastDate(this.properties).subscribe(res => {
this.lastDBLoadDate = res;
}));
this.communitySearchUtils.keyword = "";
this.fundersCtrl = this._fb.array([]);
this.filterForm = this._fb.group({
keyword: [''],
funder: this.fundersCtrl,
funder: this._fb.control(null),
sort: this._fb.control(this.sortOptions[0].value)
});
this.subscriptions.push(this.filterForm.get('keyword').valueChanges.subscribe(value => {
this.searchText = new RegExp(value, 'i');
this.subscriptions.push(this.filterForm.get('keyword').valueChanges.pipe(debounceTime(500), distinctUntilChanged()).subscribe(value => {
this.page = 1;
this.applyFilters();
}));
this._getCommunityProjects(this.page, this.filterForm.get('keyword').value,(this.filterForm.get("funder").value? this.filterForm.get("funder").value.id:null),
this.filterForm.get("sort").value.sort );
this.subscriptions.push(this.filterForm.get('funder').valueChanges.subscribe(value => {
this.page = 1;
this.applyFilters();
}));
this.subscriptions.push(this.filterForm.get('sort').valueChanges.subscribe(value => {
this.page = 1;
this.sort();
this._getCommunityProjects(this.page, this.filterForm.get('keyword').value, this.filterForm.get("funder").value? this.filterForm.get("funder").value.id:null, this.filterForm.get("sort").value.sort );
}));
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
@ -111,7 +106,8 @@ export class RemoveProjectsComponent implements OnInit {
+ this.community.communityId + ".openaire.eu" + this.properties.searchLinkToProject.split("?")[0];
this.keyword = '';
this._getCommunityProjects();
this._getCommunityFunders();
this._getCommunityProjects(1,this.keyword, null);
}
}));
}
@ -133,18 +129,13 @@ export class RemoveProjectsComponent implements OnInit {
}
public confirmedDeleteProject(data: any) {
this.subscriptions.push(this._manageCommunityProjectsService.removeProject(this.properties, this.community.communityId, this.selectedCommunityProject.id).subscribe(
this.subscriptions.push(this._manageCommunityProjectsService.removeProject(this.properties, this.community.communityId, this.selectedCommunityProject.openaireId).subscribe(
data => {
let index = this.communityProjects.indexOf(this.selectedCommunityProject);
this.communityProjects.splice(index, 1);
this.applyFilters();
this._clearCacheService.purgeBrowserCache(this.openaireEntiites.PROJECT+" removed", this.community.communityId);
NotificationHandler.rise(OpenaireEntities.PROJECT+' successfully removed!');
this.communityProjectsChanged.emit({
value: this.communityProjects,
});
this.communitySearchUtils.totalResults--;
this.communitySearchUtils.page = 1;
this._getCommunityProjects(this.communitySearchUtils.page, this.keyword,null);
},
err => {
this.handleError('An error has been occurred. Try again later!');
@ -179,29 +170,21 @@ export class RemoveProjectsComponent implements OnInit {
this.alertModalDeleteCommunity.okButtonText = "Yes";
this.alertModalDeleteCommunity.open();
}
public _getCommunityProjects() {
public getCommunityProjects() {
this._getCommunityProjects(this.communitySearchUtils.page, this.keyword,null );
}
public _getCommunityProjects(page, keyword, funder, orderBy = "name" ) {
this.communitySearchUtils.status = this.errorCodes.LOADING;
this.communityProjects = [];
this.communitySearchUtils.totalResults = 0;
this.communitySearchUtils.page = 1;
this.communitySearchUtils.keyword = "";
this.subscriptions.push(this._searchCommunityProjectsService.searchProjects(this.properties, this.community.communityId).subscribe(
this.communitySearchUtils.page = page;
this.communitySearchUtils.keyword = keyword;
this.subscriptions.push(this._searchCommunityProjectsService.searchProjectsWithPaging(this.properties, this.community.communityId, this.communitySearchUtils.page, this.resultsPerPage, this.communitySearchUtils.keyword, funder, orderBy).subscribe(
data => {
this.communityProjects = data;
this.previewCommunityProjects = this.communityProjects;
this.sort();
this.communitySearchUtils.totalResults = data.length;
this.previewCommunityProjects = data.content;
this.communitySearchUtils.totalResults = data.totalElements;
this.communitySearchUtils.status = this.errorCodes.DONE;
this.communityProjectsChanged.emit({
value: this.communityProjects,
value: this.communitySearchUtils.totalResults
});
this.createFunderFilter();
this.loading = false;
},
err => {
@ -215,90 +198,33 @@ export class RemoveProjectsComponent implements OnInit {
} else {
this.communitySearchUtils.status = this.errorCodes.NOT_AVAILABLE;
}
this.loading = false;
}
));
}
public createFunderFilter(): void {
let funders: Set<string> = new Set<string>();
this.allOptions = [];
let i;
for (i = 0; i < this.communityProjects.length; i++) {
let funder = this.communityProjects[i].funder;
if (funder && !funders.has(funder)) {
funders.add(funder);
this.allOptions.push({label: funder, value: {id: funder, label: funder}});
public _getCommunityFunders() {
this.subscriptions.push(this._searchCommunityProjectsService.getProjectFunders(this.properties, this.community.communityId).subscribe(
data => {
for (let funder of data) {
this.allFunderOptions.push({label: funder, value: {id: funder, label: funder}});
}
this.previewFunderOptions =[...this.allFunderOptions];
},
err => {
}
}
));
}
public updatePage($event) {
HelperFunctions.scroll();
this.page = $event.value;
this._getCommunityProjects(this.page, this.filterForm.get('keyword').value, null);
}
addNew() {
this.addProjects.emit();
}
public applyFilters() {
this.previewCommunityProjects = this.communityProjects.filter(project => {
return (this.filterCommunityProjectByKeyword(project) && this.filterCommunityProjectByFunder(project));
});
// check paging here!!!
if (this.previewCommunityProjects.slice((this.page - 1) * this.resultsPerPage, this.page * this.resultsPerPage).length == 0) {
this.page = 1;
}
this.sort();
}
public filterCommunityProjectByKeyword(project): boolean {
return this.searchText.toString() === ''
|| ((project.name + " " + project.acronym + " " + project.grantId + " " + project.funder)).match(this.searchText) != null;
}
public filterCommunityProjectByFunder(project): boolean {
if (this.fundersCtrl.getRawValue().length == 0) {
return true;
}
for (let funder of this.fundersCtrl.getRawValue()) {
if (project.funder.toLowerCase().indexOf(funder.label.toLowerCase()) != -1) {
return true;
}
}
return false;
}
private sort() {
let sortOption: { sort: string, descending: boolean } = this.filterForm.get('sort').value;
this.previewCommunityProjects.sort((left, right): number => {
if (sortOption.sort == "title") {
if ((left.name + left.acronym) > (right.name + right.acronym)) {
return sortOption.descending ? -1 : 1;
} else if ((left.name + left.acronym) < (right.name + right.acronym)) {
return sortOption.descending ? 1 : -1;
}
} else if (sortOption.sort == "grant") {
if (left.grantId > right.grantId) {
return sortOption.descending ? -1 : 1;
} else if (left.grantId < right.grantId) {
return sortOption.descending ? 1 : -1;
}
} else if (sortOption.sort == "funder") {
if (left.funder > right.funder) {
return sortOption.descending ? -1 : 1;
} else if (left.funder < right.funder) {
return sortOption.descending ? 1 : -1;
}
}
return 0;
});
}
public onSearchClose() {
this.communitySearchUtils.keyword = this.filterForm.get('keyword').value;
@ -313,23 +239,25 @@ export class RemoveProjectsComponent implements OnInit {
NotificationHandler.rise(message, 'danger');
}
select(value: string, event, dropdownFilter: DropdownFilterComponent) {
select(option, event, dropdownFilter: DropdownFilterComponent) {
console.log(option)
if(event.target instanceof HTMLInputElement) {
dropdownFilter.closeDropdown();
if(event.target.checked && !this.selectedFunders.find(entity => value === entity)) {
this.selectedFunders.push(value);
this.fundersCtrl.setControl(this.fundersCtrl.value.length, this._fb.control(value));
if(event.target.checked) {
this.filterForm.get("funder").setValue(option.value);
this._getCommunityProjects(1, this.filterForm.get('keyword').value, this.filterForm.get('funder').value.id );
this.previewFunderOptions =[option];
} else if(!event.target.checked) {
let index = this.selectedFunders.indexOf(value);
if(index !== -1) {
this.selectedFunders.splice(index, 1);
this.fundersCtrl.removeAt(index);
}
this.filterForm.get("funder").setValue(null);
this._getCommunityProjects(1, this.filterForm.get('keyword').value,null);
this.previewFunderOptions =[...this.allFunderOptions];
}
}
}
isSelected(value: string) {
return this.filterForm && this.filterForm.get('funder').value.find(funder => funder === value)
return this.filterForm && this.filterForm.get('funder').value && this.filterForm.get('funder').value.id === value;
}
}

@ -133,7 +133,7 @@ export class StatsComponent implements OnInit {
this._router.navigate(['/user-info'], { queryParams: { "errorCode": LoginErrorCodes.NOT_VALID, "redirectUrl": this._router.url} });
} else {
//console.log(`calling ${this.properties.adminToolsAPIURL}/communityFull/${this.communityId}`);
this.configService.communityInformationState.subscribe(
this.configService.portalAsObservable.subscribe(
res => {
console.debug(res);
if(res) {

@ -1,128 +1,337 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Subjects
<div actions>
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-middle uk-grid" uk-grid>
<div [disabled]="loading" search-input class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1"
[searchControl]="filterForm" [expandable]="true" placeholder="Search Subjects" searchInputClass="outer">
</div>
<div>
<button class="uk-button uk-button-default uk-flex uk-flex-middle"
[disabled]="loading" [class.uk-disabled]="loading"
(click)="editAllSubjects()"
uk-tooltip="title:<div><div class='uk-margin-small-bottom uk-text-bold'>Add or edit subjects</div> All the research results associated to the subjects specified here will be automatically linked to the community dashboard in the next run of OpenAIRE workflows.</div>">
<span>Add/Edit Subjects</span>
</button>
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="subjects"></community-info>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-middle uk-grid uk-margin-top" uk-grid>
<div [disabled]="showLoading" search-input class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1"
[searchControl]="filterForm" [expandable]="true" placeholder="Search Subjects" searchInputClass="outer">
</div>
<!-- <a *ngIf="!subjectsEnabled" (click)="enablePage()" class="uk-link-heading uk-text-small uk-text-uppercase"
uk-tooltip="title:<div class='uk-padding-small'>This information will be visible in <b>Subjects page</b> of Research Community Dashboard, which is <b>disabled</b>. <br> Click to enable id.</div>">
<span class="uk-text-secondary"><icon name="check_circle_outlined"></icon></span>
Enable page
</a>-->
<div>
<button class="uk-button uk-button-default uk-flex uk-flex-middle"
[disabled]="showLoading" [class.uk-disabled]="showLoading"
(click)="newSubject()"
uk-tooltip="title:<div><div class='uk-margin-small-bottom uk-text-bold'>Add new subjects</div> All the research results associated to the subjects specified here will be automatically linked to the community dashboard in the next run of OpenAIRE workflows.</div>">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-small-left">New Subject</span>
</button>
</div>
</div>
</div>
</div>
<div inner>
<div class="uk-section uk-section-small uk-position-relative" style="min-height: 60vh">
<div *ngIf="showLoading" class="uk-position-center">
<div class="uk-section uk-section-small uk-position-relative" style="min-height: 60vh">
<div *ngIf="loading" class="uk-position-center">
<loading></loading>
</div>
<div *ngIf="!showLoading">
<div *ngIf="community.subjects.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No subjects
<span *ngIf="originalSubjects.length == 0; else: notFound">for {{community.shortTitle}}</span>
<ng-template #notFound>found</ng-template>
</div>
</div>
<div *ngIf="community.subjects.length > 0">
<no-load-paging *ngIf="community.subjects.length > 0" [type]="'Subjects'"
[page]="page" [pageSize]="size" (pageChange)="updatePage($event)"
[totalResults]="community.subjects.length">
</no-load-paging>
<div class="uk-grid uk-grid-large uk-grid-match uk-child-width-1-1 uk-child-width-1-2@m uk-margin-top uk-margin-bottom" uk-grid>
<div *ngFor='let subject of currentPage; let i = index;'>
<div class="uk-card uk-card-default">
<div class="uk-card-body">
<h6 uk-tooltip="title:All the research results associated to this subjects will be automatically linked to the community dashboard."
class="uk-display-inline-block">
{{subject}}
</h6>
</div>
<div class="uk-card-footer uk-padding-remove-vertical">
<div class="uk-grid uk-grid-small uk-flex-nowrap uk-grid-divider uk-flex-right" uk-grid>
<div *ngIf="!loading">
<div *ngIf="displayedSubjects?.length == 0 && displayedSdg?.length == 0 && displayedFos?.length == 0"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No subjects</div>
</div>
<div *ngIf="displayedSubjects?.length > 0 || displayedSdg?.length > 0 || displayedFos?.length > 0">
<ul uk-tab class="uk-tab uk-margin-bottom uk-flex uk-flex-center uk-flex-left@m">
<li class="uk-active" *ngIf="displayedAllSubjects?.length" (click)="groupSubjects(displayedAllSubjects, 'all')">
<a>All ({{displayedAllSubjects.length}})</a>
</li>
<li (click)="groupSubjects(displayedSubjects, 'freeText')">
<a>Free Text ({{displayedSubjects.length}})</a>
</li>
<li (click)="groupSubjects(displayedSdg, 'sdg')">
<a>SDGs ({{displayedSdg.length}})</a>
</li>
<li (click)="groupSubjects(displayedFos, 'fos')">
<a>Fields of Science ({{displayedFos.length}})</a>
</li>
</ul>
<ul class="uk-switcher">
<li>
<ng-container *ngIf="displayedAllSubjects?.length">
<div>
<ul class="uk-nav uk-nav-default uk-flex uk-flex-wrap">
<li *ngFor="let item of groupedAllSubjects; let i = index;" class="uk-margin-right" [class.uk-margin-left]="i != 0"
[class]="indexAll == i ? 'uk-active':''" (click)="changeDisplayedSubjects(i, item)">
<a class="uk-padding-remove">{{item.group}}</a>
</li>
</ul>
</div>
<!-- View for 'All' -->
<div *ngIf="indexAll == 0 && groupedAllSubjects.length > 1" class="uk-margin-large-top uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let item of groupedAllSubjects.slice(1); let i = index;">
<div>
<h6>{{item.group}}</h6>
<div *ngFor="let subItem of item.data.slice(0, subjectsLimit)" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
<div *ngIf="item.data.length > subjectsLimit">
<a (click)="changeDisplayedSubjects(i+1, item)" class="view-more-less-link">
View all
</a>
</div>
</div>
</div>
</div>
<!-- View for a single group -->
<div *ngIf="indexAll != 0 || groupedAllSubjects.length == 1" class="uk-margin-large-top">
<div>
<div>
<h6>{{groupedAllSubjects[indexAll].group}}</h6>
<ng-container *ngIf="subjectsColumns?.length == 0; else elseBlock">
<div *ngFor="let subItem of groupedAllSubjects[indexAll].data" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</ng-container>
<ng-template #elseBlock>
<div class="uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let group of subjectsColumns">
<div *ngFor="let subItem of group" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="displayedAllSubjects?.length === 0">
<div class="uk-position-relative uk-height-medium">
<h6 class="uk-position-center uk-margin-remove">There are no subjects yet</h6>
</div>
</ng-container>
</li>
<li>
<ng-container *ngIf="displayedSubjects?.length">
<div>
<ul class="uk-nav uk-nav-default uk-flex uk-flex-wrap">
<li *ngFor="let item of groupedSubjects; let i = index;" class="uk-margin-right" [class.uk-margin-left]="i != 0"
[class]="indexSubjects == i ? 'uk-active':''" (click)="changeDisplayedSubjects(i, item)">
<a class="uk-padding-remove">{{item.group}}</a>
</li>
</ul>
</div>
<!-- View for 'All' -->
<div *ngIf="indexSubjects == 0 && groupedSubjects.length > 1" class="uk-margin-large-top uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let item of groupedSubjects.slice(1); let i = index;">
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<a (click)="editSubject(subject)"
class="uk-button uk-button-link uk-flex uk-flex-middle">
<icon name="edit" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Edit</span>
<h6>{{item.group}}</h6>
<div *ngFor="let subItem of item.data.slice(0, subjectsLimit)" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
<div *ngIf="item.data.length > subjectsLimit">
<a (click)="changeDisplayedSubjects(i+1, item)" class="view-more-less-link">
View all
</a>
</div>
</div>
</div>
</div>
<!-- View for a single group -->
<div *ngIf="indexSubjects != 0 || groupedSubjects.length == 1" class="uk-margin-large-top">
<div>
<div>
<h6>{{groupedSubjects[indexSubjects]?.group}}</h6>
<ng-container *ngIf="subjectsColumns?.length == 0; else elseBlock">
<div *ngFor="let subItem of groupedSubjects[indexSubjects]?.data" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</ng-container>
<ng-template #elseBlock>
<div class="uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let group of subjectsColumns">
<div *ngFor="let subItem of group" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="displayedSubjects?.length === 0">
<div class="uk-position-relative uk-height-medium">
<h6 class="uk-position-center uk-margin-remove">There are no subjects yet</h6>
</div>
</ng-container>
</li>
<li>
<ng-container *ngIf="displayedSdg?.length">
<div>
<ul class="uk-nav uk-nav-default uk-flex uk-flex-wrap">
<li *ngFor="let item of groupedSdg; let i = index;" class="uk-margin-right" [class.uk-margin-left]="i != 0"
[class]="indexSdg == i ? 'uk-active':''" (click)="changeDisplayedSubjects(i, item)">
<a class="uk-padding-remove">{{item.group}}</a>
</li>
</ul>
</div>
<!-- View for 'All' -->
<div *ngIf="indexSdg == 0 && groupedSdg.length > 1" class="uk-margin-large-top uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let item of groupedSdg.slice(1); let i = index;">
<div>
<div class="uk-padding-small uk-padding-remove-horizontal">
<button class="uk-button uk-button-link uk-flex uk-flex-middle"
(click)="removeModalOpen(subject, i)">
<icon name="delete" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Delete</span>
</button>
<h6>{{item.group}}</h6>
<div *ngFor="let subItem of item.data.slice(0, subjectsLimit)" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
<div *ngIf="item.data.length > subjectsLimit">
<a (click)="changeDisplayedSubjects(i+1, item)" class="view-more-less-link">
View all
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="uk-margin-small-top">
<paging-no-load [currentPage]="page" [totalResults]="community.subjects.length" [size]="size"
(pageChange)="updatePage($event)" customClasses="uk-flex-right@m uk-flex-center">
</paging-no-load>
</div>
</div>
</div>
</div>
</div>
<!-- View for a single group -->
<div *ngIf="indexSdg != 0 || groupedSdg.length == 1" class="uk-margin-large-top">
<div>
<div>
<h6>{{groupedSdg[indexSdg].group}}</h6>
<ng-container *ngIf="subjectsColumns?.length == 0; else elseBlock">
<div *ngFor="let subItem of groupedSdg[indexSdg].data" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</ng-container>
<ng-template #elseBlock>
<div class="uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let group of subjectsColumns">
<div *ngFor="let subItem of group" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="displayedSdg?.length === 0">
<div class="uk-position-relative uk-height-medium">
<h6 class="uk-position-center uk-margin-remove">There are no subjects yet</h6>
</div>
</ng-container>
</li>
<li>
<ng-container *ngIf="displayedFos?.length">
<div>
<ul class="uk-nav uk-nav-default uk-flex uk-flex-wrap">
<li *ngFor="let item of groupedFos; let i = index;" class="uk-margin-right" [class.uk-margin-left]="i != 0"
[class]="indexFos == i ? 'uk-active':''" (click)="changeDisplayedSubjects(i, item)">
<a class="uk-padding-remove">{{item.group}}</a>
</li>
</ul>
</div>
<!-- View for 'All' -->
<div *ngIf="indexFos == 0 && groupedFos.length > 1" class="uk-margin-large-top uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let item of groupedFos.slice(1); let i = index;">
<div>
<h6>{{item.group}}</h6>
<div *ngFor="let subItem of item.data.slice(0, subjectsLimit)" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
<div *ngIf="item.data.length > subjectsLimit">
<a (click)="changeDisplayedSubjects(i+1, item)" class="view-more-less-link">
View all
</a>
</div>
</div>
</div>
</div>
<!-- View for a single group -->
<div *ngIf="indexFos != 0 || groupedFos.length == 1" class="uk-margin-large-top">
<div>
<div>
<h6>{{groupedFos[indexFos].group}}</h6>
<ng-container *ngIf="subjectsColumns?.length == 0; else elseBlock">
<div *ngFor="let subItem of groupedFos[indexFos].data" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</ng-container>
<ng-template #elseBlock>
<div class="uk-grid uk-child-width-1-4@m" uk-grid>
<div *ngFor="let group of subjectsColumns">
<div *ngFor="let subItem of group" class="uk-margin-small-bottom">
<span [attr.uk-tooltip]="subItem.length > maxCharacters ? 'cls: uk-active' : 'cls: uk-invisible'" [title]="subItem">
{{subItem.length > maxCharacters ? subItem.substring(0,maxCharacters)+'...' : subItem}}
</span>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</ng-container>
<ng-container *ngIf="displayedFos?.length === 0">
<div class="uk-position-relative uk-height-medium">
<h6 class="uk-position-center uk-margin-remove">There are no subjects yet</h6>
</div>
</ng-container>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<modal-alert #deleteModal (alertOutput)="saveSubjects()" [overflowBody]="false" classTitle="uk-background-primary uk-light"></modal-alert>
<fs-modal #fsModal classBody="uk-container-small" (okEmitter)="saveSubjects()" [okButtonDisabled]="myForm && (myForm.invalid || !myForm.dirty)">
<form *ngIf="myForm">
<div class="uk-margin-top uk-flex-center uk-flex uk-margin-medium-bottom">
<a *ngIf="!isEditModal" (click)="addSubjectInForm()">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon>
<span class="uk-margin-xsmall-left">Add Subject</span>
</button>
</a>
</div>
<div class="uk-grid uk-child-width-1-1" uk-grid>
<div *ngFor=" let control of myForm.controls; index as i" class="uk-flex uk-flex-middle">
<div input [formInput]="myForm.controls[i]" type="text"
placeholder="Type subjects as free text keywords" class="uk-width-expand"></div>
<div *ngIf="!isEditModal" class="uk-width-auto uk-flex uk-flex-center uk-margin-left">
<button class="uk-close uk-icon" [class.uk-invisible]="myForm.length === 1"
(click)="removeSubjectInForm(i)">
<icon name="close" [flex]="true" [ratio]="1.5"></icon>
</button>
</div>
</div>
</div>
</form>
</fs-modal>
<!--<modal-alert #enablePageModal (alertOutput)="enablePage()">
<div class="uk-padding uk-padding-remove-horizontal">
This information will be visible in <span class="uk-text-bold">Subjects page</span> of Research Community
Dashboard, which is <span class="uk-text-bold">disabled</span>.
Do you want to <span class="uk-text-bold">enable</span> it now?
<fs-modal #fsModal classBody="uk-container-large" (okEmitter)="saveAllSubjects()" [okButtonDisabled]="!hasChanges && !sdgSelection.hasChanges && !fosSelection.hasChanges">
<div>
<ul uk-tab #modalTabs class="uk-tab uk-margin-top uk-margin-large-bottom uk-flex uk-flex-center uk-flex-left@m">
<li class="uk-active">
<a>Free Text ({{displayedSubjects.length}})</a>
</li>
<li>
<a>SDGs ({{sdgSelection.getSelectedSubjects().length}})<span *ngIf="sdgSelection.hasChanges">*</span></a>
</li>
<li>
<a>Fields of Science ({{fosSelection.getSelectedSubjects().length}})<span *ngIf="fosSelection.hasChanges">*</span></a>
</li>
</ul>
<ul class="uk-switcher">
<li *ngIf="subjectsForm">
<div #addSubjectsInput input [type]="'chips'" [formInput]="subjectsForm" [inputClass]="'flat small'" [extendEnter]="onEnter"
[separators]="[',', 'enter']" [visibleChips]="3" class="uk-width-1-1 uk-width-xlarge@m"
[placeholder]="{static: true, label: 'Type subjects as free text keywords'}">
<div tools class="uk-flex uk-flex-right">
<button (click)="addSubjectsIntoList()" class="uk-button uk-button-link uk-margin-xsmall-left uk-margin-right">add</button>
</div>
<div note class="uk-text-xsmall">Separate subjects with commas</div>
</div>
<div class="uk-margin-large-top">
<span *ngFor="let subject of displayedSubjects; let i = index;"
class="uk-label uk-label-primary uk-flex-inline uk-flex-middle uk-margin-right uk-margin-bottom">
<span class="uk-margin-small-right uk-text-truncate">{{subject}}</span>
<button (click)="removeSubjectFromList(i)" class="uk-close uk-icon">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</div>
</li>
<li>
<sdg-selection #sdgSelection [subjects]="displayedSdg" [isFeedback]="false"></sdg-selection>
</li>
<li>
<fos-selection #fosSelection [subjects]="displayedFos" [inModal]="true"></fos-selection>
</li>
</ul>
</div>
</modal-alert>-->
</fs-modal>

@ -1,6 +1,6 @@
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
import {UntypedFormArray, UntypedFormBuilder, UntypedFormControl} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router';
import {ActivatedRoute} from '@angular/router';
import {CommunityService} from '../../../openaireLibrary/connect/community/community.service';
import {SubjectsService} from '../subjects.service';
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties';
@ -8,334 +8,376 @@ import {Title} from '@angular/platform-browser';
import {properties} from '../../../../environments/environment';
import {AlertModal} from '../../../openaireLibrary/utils/modal/alert';
import {SearchInputComponent} from '../../../openaireLibrary/sharedComponents/search-input/search-input.component';
import {Subscription} from 'rxjs';
import {forkJoin, Subscription} from 'rxjs';
import {CommunityInfo} from '../../../openaireLibrary/connect/community/communityInfo';
import {FullScreenModalComponent} from 'src/app/openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.component';
import {
FullScreenModalComponent
} from 'src/app/openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.component';
import {HelperFunctions} from 'src/app/openaireLibrary/utils/HelperFunctions.class';
import {NotificationHandler} from "../../../openaireLibrary/utils/notification-handler";
import {ClearCacheService} from "../../../openaireLibrary/services/clear-cache.service";
import {SdgSelectionComponent} from '../../../openaireLibrary/sdg/sdg-selection/sdg-selection.component';
import {FosSelectionComponent} from '../../../openaireLibrary/fos/fos-selection/fos-selection.component';
import {InputComponent} from "../../../openaireLibrary/sharedComponents/input/input.component";
declare var UIkit: any;
@Component({
selector: 'subjects-edit-form',
templateUrl: './subjects-edit-form.component.html',
selector: 'subjects-edit-form',
templateUrl: './subjects-edit-form.component.html',
})
export class SubjectsEditFormComponent implements OnInit {
myForm = new UntypedFormArray([new UntypedFormControl({subject: ''})]);
public showLoading = true;
public res = [];
params: any;
public communityId: string = null;
public community: CommunityInfo = null;
public properties: EnvProperties = properties;
public edit = null;
public originalSubjects = [];
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
@ViewChild('fsModal', {static: true}) fullscreen: FullScreenModalComponent;
page = 1;
size = 10;
selectedSubjects = [];
isEditModal: boolean = false;
public selectedKeyword: string;
@ViewChild('searchInputComponent') searchInputComponent: SearchInputComponent;
public filterForm: UntypedFormControl;
private subscriptions: any[] = [];
/*//Check again functionality to enable page
subjectsPage;
@ViewChild('enablePageModal') enablePageModal: AlertModal;*/
constructor(private element: ElementRef,
private route: ActivatedRoute,
private _router: Router,
public _fb: UntypedFormBuilder,
private title: Title,
// private _helpContentService: HelpContentService,
private _communityService: CommunityService,
private _subjectsService: SubjectsService,
private _clearCacheService: ClearCacheService
) {
}
ngOnInit() {
this.filterForm = this._fb.control('');
this.subscriptions.push(this.filterForm.valueChanges.subscribe(value => {
this.page = 1;
this.community.subjects = this.originalSubjects.filter(subject => {
return !value || subject.toLowerCase().indexOf(value.toLowerCase()) != -1
});
}));
this.subscriptions.push(this.route.params.subscribe(
params => {
this.communityId = params['community'];
this.title.setTitle(this.communityId.toUpperCase() + ' | Subjects');
this.showLoading = true;
this.subscriptions.push(this._communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
this.params = {
community: encodeURIComponent(
'"' + community.queryId + '"')
};
this.community.subjects.sort((n1,n2)=> {
if (n1.toLowerCase() > n2.toLowerCase()) {
return 1;
}
if (n1.toLowerCase() < n2.toLowerCase()) {
return -1;
}
return 0;
properties: EnvProperties = properties;
communityId: string = null;
community: CommunityInfo = null;
loading = true;
params: any;
private subscriptions: any[] = [];
filterForm: UntypedFormControl;
subjectsForm = new UntypedFormArray([]);
hasChanges: boolean = false;
originalAllSubjects = [];
originalSubjects = [];
originalSdg = [];
originalFos = [];
displayedAllSubjects = [];
displayedSubjects = [];
displayedSdg = [];
displayedFos = [];
groupedAllSubjects = [];
groupedSubjects = [];
groupedSdg = [];
groupedFos = [];
subjectsColumns = [];
subjectsLimit: number = 6;
maxCharacters: number = 25;
activeTab: 'all' | 'freeText' | 'sdg' | 'fos' = 'all';
indexAll: number = 0;
indexSubjects: number = 0;
indexSdg: number = 0;
indexFos: number = 0;
@ViewChild('addSubjectsInput') addSubjectsInput: InputComponent;
@ViewChild('editModal') editModal: AlertModal;
@ViewChild('deleteModal') deleteModal: AlertModal;
@ViewChild('fsModal', {static: true}) fullscreen: FullScreenModalComponent;
@ViewChild('modalTabs') modalTabs: ElementRef;
@ViewChild('sdgSelection') sdgSelection: SdgSelectionComponent;
@ViewChild('fosSelection') fosSelection: FosSelectionComponent;
onEnter: () => void = () => {
this.addSubjectsIntoList();
}
constructor(private route: ActivatedRoute,
public _fb: UntypedFormBuilder,
private title: Title,
private _communityService: CommunityService,
private _subjectsService: SubjectsService,
private _clearCacheService: ClearCacheService) {
}
ngOnInit() {
this.filterForm = this._fb.control('');
this.subscriptions.push(this.filterForm.valueChanges.subscribe(value => {
this.displayedAllSubjects = this.originalAllSubjects.filter(subject => {
return !value || subject.toLowerCase().indexOf(value.toLowerCase()) != -1
});
this.displayedSubjects = this.originalSubjects.filter(subject => {
return !value || subject.toLowerCase().indexOf(value.toLowerCase()) != -1
});
this.displayedSdg = this.originalSdg.filter(subject => {
return !value || subject.toLowerCase().indexOf(value.toLowerCase()) != -1
});
this.displayedFos = this.originalFos.filter(subject => {
return !value || subject.toLowerCase().indexOf(value.toLowerCase()) != -1
});
if (this.activeTab === 'all') {
this.groupSubjects(this.displayedAllSubjects, 'all');
} else if (this.activeTab === 'freeText') {
this.groupSubjects(this.displayedSubjects, 'freeText');
} else if (this.activeTab === 'sdg') {
this.groupSubjects(this.displayedSdg, 'sdg');
} else if (this.activeTab === 'fos') {
this.groupSubjects(this.displayedFos, 'fos');
}
}));
this.subscriptions.push(this.route.params.subscribe(
params => {
this.communityId = params['community'];
this.title.setTitle(this.communityId.toUpperCase() + ' | Subjects');
this.loading = true;
this.subscriptions.push(this._communityService.getCommunityAsObservable().subscribe(
community => {
this.community = community;
this.params = {
community: encodeURIComponent(
'"' + community.queryId + '"')
};
this.community.subjects.sort((n1, n2) => {
if (n1.toLowerCase() > n2.toLowerCase()) {
return 1;
}
if (n1.toLowerCase() < n2.toLowerCase()) {
return -1;
}
return 0;
});
this.displayedSubjects = HelperFunctions.copy(this.community.subjects);
this.displayedSdg = this.community.sdg;
this.displayedFos = this.community.fos;
this.displayedAllSubjects = [...this.displayedSubjects, ...this.displayedSdg, ...this.displayedFos];
this.groupSubjects(this.displayedAllSubjects, 'all');
this.originalAllSubjects = HelperFunctions.copy(this.displayedAllSubjects);
this.originalSubjects = HelperFunctions.copy(this.displayedSubjects);
this.originalSdg = HelperFunctions.copy(this.displayedSdg);
this.originalFos = HelperFunctions.copy(this.displayedFos);
this.loading = false;
},
error => this.handleUpdateError('System error retrieving community profile', error)
));
}));
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
this.originalSubjects = [];
for (let i = 0; i < this.community.subjects.length; i++) {
this.originalSubjects.push(this.community.subjects[i]);
public groupSubjects(subjects: string[], type: string) {
if (subjects.length === 0) {
return [];
}
subjects.sort((a, b) => a.localeCompare(b));
if (type === 'all') {
this.indexAll = 0;
this.activeTab = 'all';
this.groupedAllSubjects = Object.values(
subjects.reduce((acc, subject) => {
let firstLetter = subject[0].toLocaleUpperCase();
if (!acc[firstLetter]) {
acc[firstLetter] = {group: firstLetter, data: [subject]};
} else {
acc[firstLetter].data.push(subject);
}
return acc;
}, {})
)
if (subjects.length > 1) {
this.groupedAllSubjects.unshift({group: 'All', data: subjects});
}
}
if (type === 'freeText') {
this.indexSubjects = 0;
this.activeTab = 'freeText';
this.groupedSubjects = Object.values(
subjects.reduce((acc, subject) => {
let firstLetter = subject[0].toLocaleUpperCase();
if (!acc[firstLetter]) {
acc[firstLetter] = {group: firstLetter, data: [subject]};
} else {
acc[firstLetter].data.push(subject);
}
return acc;
}, {})
)
if (subjects.length > 1) {
this.groupedSubjects.unshift({group: 'All', data: subjects});
}
}
if (type === 'sdg') {
this.indexSdg = 0;
this.activeTab = 'sdg';
this.groupedSdg = Object.values(
subjects.reduce((acc, subject) => {
let firstLetter = subject[0].toLocaleUpperCase();
if (!acc[firstLetter]) {
acc[firstLetter] = {group: firstLetter, data: [subject]};
} else {
acc[firstLetter].data.push(subject);
}
return acc;
}, {})
)
if (subjects.length > 1) {
this.groupedSdg.unshift({group: 'All', data: subjects});
}
}
if (type === 'fos') {
this.indexFos = 0;
this.activeTab = 'fos';
this.groupedFos = Object.values(
subjects.reduce((acc, subject) => {
let key = subject.substring(0, 2).toLocaleUpperCase();
if (!acc[key]) {
acc[key] = {group: key, data: [subject]};
} else {
acc[key].data.push(subject);
}
return acc;
}, {})
)
if (subjects.length > 1) {
this.groupedFos.unshift({group: 'All', data: subjects});
}
if (this.community.subjects.length === 0) {
this.community.subjects.push('');
}
}
public changeDisplayedSubjects(i, group) {
this.subjectsColumns = [];
if (this.activeTab === 'all') {
this.indexAll = i;
} else if (this.activeTab === 'freeText') {
this.indexSubjects = i;
} else if (this.activeTab === 'sdg') {
this.indexSdg = i;
} else if (this.activeTab === 'fos') {
this.indexFos = i;
}
if (group.data.length > this.subjectsLimit && group.group != 'All') {
this.divideSubjects(group);
}
}
public divideSubjects(group) {
let columns = [];
for (let i = 0; i < (group.data.length / this.subjectsLimit); i++) {
columns.push(group.data.slice(i * this.subjectsLimit, ((i + 1) * this.subjectsLimit)));
}
this.subjectsColumns = columns;
}
public getSubjectsExistOnlyInFirst(firstArray: string[], secondArray: string[]): string[] {
const difference = [];
for (let i = 0; i < firstArray.length; i++) {
if (secondArray.indexOf(firstArray[i]) === -1) {
difference.push(firstArray[i]);
}
this.showLoading = false;
},
error => this.handleUpdateError('System error retrieving community profile', error)
));
// this.getSubjectsPageStatus();
}));
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
private removeModalOpen(subject: string, i: any) {
this.selectedSubjects = [subject];
this.reset(['']);
this.deleteModal.cancelButton = true;
this.deleteModal.okButton = true;
this.deleteModal.alertTitle = 'Delete Subject';
this.deleteModal.message = 'Are you sure you want to delete this subject?';
this.deleteModal.okButtonText = 'Yes';
this.deleteModal.cancelButtonText = 'No';
this.deleteModal.open();
}
public getSubjectsExistOnlyInFirst(firstArray: string[], secondArray: string[]): string[] {
const difference = [];
for (let i = 0; i < firstArray.length; i++) {
if (secondArray.indexOf(firstArray[i]) === -1) {
difference.push(firstArray[i]);
}
}
return difference;
}
return difference;
}
public saveSubjects() {
if (this.communityId != null && this.communityId !== '') {
this.showLoading = true;
const subjectsToDeleteAr = this.getSubjectsExistOnlyInFirst(this.selectedSubjects, this.myForm.getRawValue());
const subjectsToAddAr = this.getSubjectsExistOnlyInFirst(this.myForm.getRawValue(), this.selectedSubjects);
const subjectsToDelete = this.getNonEmptyItems(subjectsToDeleteAr);
const subjectsToAdd = this.getNonEmptyItems(subjectsToAddAr);
if (subjectsToAdd.length > 0 && subjectsToDelete.length > 0) {
this.subscriptions.push(this._subjectsService.removeSubjects(
this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete).subscribe(res =>{
this.subscriptions.push(this._subjectsService.addSubjects(
this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd).subscribe(res => {
this.afterUpdateActions(res, "added");
}));
}));
} else if (subjectsToAdd.length > 0) {
this.subscriptions.push(this._subjectsService.addSubjects(
this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd).subscribe(res => {
this.afterUpdateActions(res, "added");
},
error => this.handleUpdateError('System error updating subjects', error)
));
} else if (subjectsToDelete.length > 0) {
this.subscriptions.push(this._subjectsService.removeSubjects(
this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete).subscribe(res => {
this.afterUpdateActions(res, "deleted");
},
error => this.handleUpdateError('System error updating subjects', error)
));
}
}
}
handleUpdateError(message: string, error = null) {
if(error) {
console.error(error)
public editAllSubjects() {
UIkit.tab(this.modalTabs.nativeElement).show(0);
this.displayedSubjects = HelperFunctions.copy(this.community.subjects);
this.sdgSelection.reset();
this.sdgSelection.sdgs.markAsPristine();
this.fosSelection.reset();
this.fosSelection.fosOptions.markAsPristine();
this.fullscreen.title = "Add/Edit Subjects";
this.fullscreen.okButtonText = "Save";
this.fullscreen.back = true;
this.fullscreen.okButton = true;
this.fullscreen.open();
}
NotificationHandler.rise(message, 'danger');
this.showLoading = false;
}
afterUpdateActions(res, message: string) {
this._communityService.setCommunity(this._communityService.parseCommunity(res));
this.community.subjects = res['subjects'];
this.originalSubjects = [];
for (let i = 0; i < this.community.subjects.length; i++) {
this.originalSubjects.push(this.community.subjects[i]);
public addSubjectsIntoList() {
if (this.addSubjectsInput.searchControl.getRawValue()) {
this.addSubjectsInput.add(null, true);
}
this.subjectsForm.getRawValue().forEach(element => {
this.displayedSubjects.unshift(element);
});
this.subjectsForm.clear();
this.hasChanges = true;
}
this.originalSubjects.sort((n1,n2)=> {
if (n1.toLowerCase() > n2.toLowerCase()) {
return 1;
}
if (n1.toLowerCase() < n2.toLowerCase()) {
return -1;
}
return 0;
});
this.page = 1;
this.community.subjects = this.originalSubjects.filter(subject => {
return !this.filterForm.value || subject.toLowerCase().indexOf(this.filterForm.value.toLowerCase()) != -1
}).sort();
this._clearCacheService.purgeBrowserCache("Subject "+message, this.communityId);
NotificationHandler.rise('Subject successfully ' + message + '!')
this.showLoading = false;
}
private getNonEmptyItems(data: string[]): string[] {
const length = data.length;
const arrayNonEmpty = new Array<string>();
let j = 0;
for (let i = 0; i < length; i++) {
if (this.isEmpty(data[i])) {
} else if (this.isNonEmpty(data[i])) {
arrayNonEmpty[j] = data[i];
j++;
}
public removeSubjectFromList(i) {
this.displayedSubjects.splice(i, 1);
this.hasChanges = true;
}
return arrayNonEmpty;
}
private isEmpty(data: string): boolean {
if (data !== undefined && !data.replace(/\s/g, '').length) {
return true;
} else {
return false;
public saveAllSubjects() {
let selectedSdg = this.sdgSelection.getSelectedSubjects().map(a => a.id);
let selectedFos = this.fosSelection.getSelectedSubjects().map(a => a.id);
let requests = [
...this.saveSubjects(this.community.subjects, this.displayedSubjects, 'subjects'),
...this.saveSubjects(this.community.sdg, selectedSdg, 'sdg'),
...this.saveSubjects(this.community.fos, selectedFos, 'fos')
];
this.subscriptions.push(forkJoin(requests).subscribe(res => {
this.afterUpdateActions(res, "updated");
}));
}
}
private isNonEmpty(data: string): boolean {
if (data !== undefined && data != null) {
return true;
} else {
return false;
public saveSubjects(subjects, displayedSubjects, type: string) {
if (this.communityId != null && this.communityId !== '') {
this.loading = true;
const subjectsToDeleteAr = this.getSubjectsExistOnlyInFirst(subjects, displayedSubjects);
const subjectsToAddAr = this.getSubjectsExistOnlyInFirst(displayedSubjects, subjects);
const subjectsToDelete = this.getNonEmptyItems(subjectsToDeleteAr);
const subjectsToAdd = this.getNonEmptyItems(subjectsToAddAr);
let requests = [];
if (subjectsToDelete.length > 0) {
requests.push(this._subjectsService.removeSubjects(
this.properties.communityAPI + this.communityId + '/' + type, subjectsToDelete))
}
if (subjectsToAdd.length > 0) {
requests.push(this._subjectsService.addSubjects(
this.properties.communityAPI + this.communityId + '/' + type, subjectsToAdd))
}
return requests;
}
}
}
public addSubjectInForm() {
this.myForm.push(new UntypedFormControl(''));
}
public removeSubjectInForm(i: number) {
this.myForm.removeAt(i);
}
public reset(subjects: string[]) {
this.myForm = new UntypedFormArray([]);
for (let subject in subjects) {
this.myForm.push(new UntypedFormControl(''));
handleUpdateError(message: string, error = null) {
if (error) {
console.error(error)
}
NotificationHandler.rise(message, 'danger');
this.loading = false;
}
this.myForm.patchValue(subjects);
}
newSubject() {
this.isEditModal = false;
this.selectedSubjects = [];
this.reset([""]);
this.fullscreen.title = "Add Subject";
this.fullscreen.okButtonText = "Save";
this.fullscreen.back = true;
this.fullscreen.okButton = true;
this.fullscreen.open();
}
get currentPage() {
if(this.community.subjects) {
return this.community.subjects.slice((this.page - 1) * this.size, this.page * this.size);
} else {
return [];
afterUpdateActions(response, message: string) {
response.forEach(res => {
if (res.subjects) {
this.community.subjects = res.subjects;
} else if (res.sdg) {
this.community.sdg = res.sdg;
} else if (res.fos) {
this.community.fos = res.fos;
}
});
this._communityService.updateSubjects(this.community.subjects, this.community.fos, this.community.sdg);
this._clearCacheService.purgeBrowserCache("Subjects " + message, this.communityId);
NotificationHandler.rise('Subjects successfully ' + message + '!')
this.loading = false;
}
}
public updatePage(event) {
this.page = event.value;
HelperFunctions.scroll();
}
public editSubject(subject: string) {
this.isEditModal = true;
this.selectedSubjects = [subject];
this.reset([subject]);
this.fullscreen.title = "Edit Subject";
this.fullscreen.okButtonText = "Save";
this.fullscreen.back = true;
this.fullscreen.okButton = true;
this.fullscreen.open();
}
private formModalOpen(title: string, yesBtn: string) {
this.editModal.okButtonLeft = false;
this.editModal.cancelButton = true;
this.editModal.okButton = true;
this.editModal.alertTitle = title;
this.editModal.okButtonText = yesBtn;
this.editModal.open();
}
public onSearchClose() {
this.selectedKeyword = this.filterForm.value;
}
public resetInput() {
this.selectedKeyword = null;
this.searchInputComponent.reset()
}
/*
//Check again functionality to enable page
private getSubjectsPageStatus() {
this._helpContentService.getCommunityPagesByRoute(this.communityId, '/subjects', this.properties.adminToolsAPIURL).subscribe((page) => {
this.subjectsPage = page;
});
}
public get subjectsEnabled(): boolean {
return !this.subjectsPage || this.subjectsPage.isEnabled;
}
enablePage() {
this._helpContentService.togglePages(this.communityId, [this.subjectsPage._id], true, this.properties.adminToolsAPIURL).subscribe(() => {
this.subjectsPage.isEnabled = true;
UIkit.notification('Curators Page has been <b>enabled successfully</b>', {
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
},error => {
this.subjectsPage.isEnabled = false;
UIkit.notification('An error occured', {
status: 'danger',
timeout: 6000,
pos: 'bottom-right'
});
});
}
private getNonEmptyItems(data: string[]): string[] {
const length = data.length;
const arrayNonEmpty = new Array<string>();
let j = 0;
for (let i = 0; i < length; i++) {
if (this.isEmpty(data[i])) {
} else if (this.isNonEmpty(data[i])) {
arrayNonEmpty[j] = data[i];
j++;
}
}
return arrayNonEmpty;
}
private curatorsEnabledOpen() {
this.enablePageModal.okButtonLeft = false;
this.enablePageModal.alertTitle = 'Enable Subjects Page';
this.enablePageModal.okButtonText = 'Yes';
this.enablePageModal.cancelButtonText = 'No';
this.enablePageModal.open();
}*/
private isEmpty(data: string): boolean {
if (data !== undefined && !data.replace(/\s/g, '').length) {
return true;
} else {
return false;
}
}
private isNonEmpty(data: string): boolean {
if (data !== undefined && data != null) {
return true;
} else {
return false;
}
}
}

@ -13,14 +13,17 @@ import {AlertModalModule} from '../../../openaireLibrary/utils/modal/alertModal.
import {NoLoadPaging} from '../../../openaireLibrary/searchPages/searchUtils/no-load-paging.module';
import {LoadingModule} from '../../../openaireLibrary/utils/loading/loading.module';
import {InputModule} from '../../../openaireLibrary/sharedComponents/input/input.module';
import {CommunityInfoModule} from '../../community-info/community-info.module';
import {SearchInputModule} from '../../../openaireLibrary/sharedComponents/search-input/search-input.module';
import {FullScreenModalModule} from 'src/app/openaireLibrary/utils/modal/full-screen-modal/full-screen-modal.module';
import {PagingModule} from "../../../openaireLibrary/utils/paging.module";
import {SdgSelectionModule} from '../../../openaireLibrary/sdg/sdg-selection/sdg-selection.module';
import {FosSelectionModule} from '../../../openaireLibrary/fos/fos-selection/fos-selection.module';
@NgModule({
imports: [
SubjectsEditFormRoutingModule, CommonModule, FormsModule, RouterModule, PageContentModule, IconsModule, AlertModalModule, NoLoadPaging, LoadingModule, InputModule, CommunityInfoModule, SearchInputModule, FullScreenModalModule, PagingModule
SubjectsEditFormRoutingModule, CommonModule, FormsModule, RouterModule,
PageContentModule, IconsModule, AlertModalModule, NoLoadPaging, LoadingModule, InputModule,
SearchInputModule, FullScreenModalModule, PagingModule, SdgSelectionModule, FosSelectionModule
],
declarations: [
SubjectsEditFormComponent

@ -1,11 +1,5 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Notification Settings</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<users-tabs tab="notifications"></users-tabs>
</div>
<div actions>

@ -25,19 +25,11 @@ declare var UIkit;
template: `
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Personal Info &
Affiliations
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<users-tabs tab="personal"></users-tabs>
</div>
<div actions>
<div class="uk-container uk-section-xsmall">
<div class="uk-flex uk-flex-center uk-flex-right@m">
<div class="uk-container uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-middle uk-flex-center uk-flex-right@m">
<button class="uk-button uk-button-secondary" [class.uk-disabled]="!hasChanged || loading"
[disabled]="!hasChanged || loading"
(click)="reset()">Reset
@ -76,6 +68,16 @@ declare var UIkit;
<div class="uk-width-expand">
<div input class="uk-width-large@m uk-width-1-1" placeholder="Name"
[formInput]="curatorFb.get('name')" inputClass="border-bottom normal-font-size"></div>
<div class="uk-width-1-1 uk-margin-small-top">
<mat-slide-toggle class="uk-width-small uk-margin-small-top"
uk-tooltip="title: If your personal info is visible, it will appear in the Gateway. Otherwise, not.; pos: bottom"
[formControl]="curatorFb.get('visible')">
<span class="uk-flex uk-flex-center">
{{curatorFb.get('visible').getRawValue()?' Visible':'Invisible'}}
<icon *ngIf="!curatorFb.get('visible').getRawValue()" class="uk-margin-small-left uk-text-warning" name="warning" flex="true"></icon>
</span>
</mat-slide-toggle>
</div>
</div>
</div>
<div input class="uk-width-1-1" placeholder="Biography"
@ -264,6 +266,7 @@ export class PersonalInfoComponent implements OnInit, OnDestroy {
this.curator.affiliations = [];
this.curator.bio = '';
this.curator.photo = null;
this.curator.visible = false;
}
this.curatorsPageStatus();
}
@ -289,7 +292,8 @@ export class PersonalInfoComponent implements OnInit, OnDestroy {
bio: this.fb.control(this.curator.bio),
email: this.fb.control(this.curator.email),
photo: this.fb.control(this.curator.photo),
affiliations: affiliations
affiliations: affiliations,
visible: this.fb.control(this.curator.visible)
});
if (this.curator.photo) {
this.photo = this.properties.utilsService + '/download/' + this.curator.photo;

@ -13,13 +13,15 @@ import {InputModule} from "../../../openaireLibrary/sharedComponents/input/input
import {IconsModule} from "../../../openaireLibrary/utils/icons/icons.module";
import {UrlPrefixModule} from "../../../openaireLibrary/utils/pipes/url-prefix.module";
import {HelpContentService} from "../../../services/help-content.service";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule.forChild([
{path: '', component: PersonalInfoComponent}
]),
AlertModalModule, PageContentModule, UsersTabsModule, LoadingModule, ReactiveFormsModule, InputModule, IconsModule, UrlPrefixModule
AlertModalModule, PageContentModule, UsersTabsModule, LoadingModule, ReactiveFormsModule, InputModule, IconsModule, UrlPrefixModule,
MatSlideToggleModule
],
declarations: [
PersonalInfoComponent

@ -12,13 +12,8 @@ import {CommunityInfo} from "../../../openaireLibrary/connect/community/communit
selector: 'users-managers',
template: `
<role-users [id]="community.communityId" [type]="community.type" [name]="community.shortTitle" [inviteDisableMessage]="inviteDisableMessage"
[link]="link" [role]="'manager'" [message]="message" [emailComposer]="emailComposer">
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-margin-remove uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Users</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
[link]="link" [role]="'manager'" [deleteAuthorizationLevel]="'manager'"
[message]="message" [emailComposer]="emailComposer">
<users-tabs tab="manager"></users-tabs>
</role-users>
`
@ -30,12 +25,11 @@ export class UsersManagersComponent implements OnInit {
public message: string;
public inviteDisableMessage: string;
public emailComposer: Function = (name, recipient, role):Email => {
return Composer.composeEmailForCommunityDashboard(name, recipient);
return Composer.composeEmailForCommunityDashboard(name, role, recipient);
}
private subscriptions: any[] = [];
constructor(private communityService: CommunityService,
private route: ActivatedRoute,
private title: Title) {
}
@ -48,7 +42,7 @@ export class UsersManagersComponent implements OnInit {
this.link = this.getURL(this.community.communityId);
this.message = 'A manager has the right to access the administration part of Research Community Dashboard, ' +
'where he is able to customize and manage the content, invite other users as managers or members.';
if(community.status === "hidden") {
if(community.isPrivate()) {
this.inviteDisableMessage = "Community's status is Hidden and invitation to manage the Research community dashboard is disabled. Update the community status to enable invitations."
}
this.loading = false;

@ -4,30 +4,36 @@ import {ActivatedRoute} from "@angular/router";
import {CommunityService} from "../../../openaireLibrary/connect/community/community.service";
import {Subscriber} from "rxjs";
import {CommunityInfo} from "../../../openaireLibrary/connect/community/communityInfo";
import {Email} from "../../../openaireLibrary/utils/email/email";
import {Composer} from "../../../openaireLibrary/utils/email/composer";
import {properties} from "../../../../environments/environment";
@Component({
selector: 'users-subscribers',
template: `
<subscribers [id]="community.communityId" [type]="'community'" [name]="community.shortTitle"
<subscribers *ngIf="community.isOpen()" [id]="community.communityId" [type]="'community'" [name]="community.shortTitle"
[inviteDisableMessage]="inviteDisableMessage">
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Users</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<users-tabs tab="member"></users-tabs>
</subscribers>
<role-users *ngIf="!community.isOpen()" [id]="community.communityId" [type]="community.type" [name]="community.shortTitle" [inviteDisableMessage]="inviteDisableMessage"
[link]="link" [role]="'member'"
[message]="message" [emailComposer]="emailComposer">
<users-tabs tab="member"></users-tabs>
</role-users>
`
})
export class UsersSubscribersComponent implements OnInit {
public community: CommunityInfo;
public link: string;
public loading: boolean;
public message: string;
public inviteDisableMessage: string;
public emailComposer: Function = (name, recipient, role):Email => {
return Composer.composeEmailForCommunityDashboard(name, role, recipient);
}
private subscriptions: any[] = [];
constructor(private communityService: CommunityService,
private route: ActivatedRoute,
private title: Title) {
}
@ -36,9 +42,12 @@ export class UsersSubscribersComponent implements OnInit {
this.subscriptions.push(this.communityService.getCommunityAsObservable().subscribe(community => {
if(community) {
this.community = community;
this.title.setTitle(this.community.shortTitle.toUpperCase() + " | Subscribers");
if(community.status !== "all") {
this.inviteDisableMessage = "Community's status is " + (community.status === 'manager'?'Visible to managers':'Hidden') + " and invitation to join the Research community dashboard is disabled. Update the community status to enable invitations."
this.title.setTitle(this.community.shortTitle.toUpperCase() + " | Members");
this.link = this.getURL(this.community.communityId);
this.message = 'A member can access the community dashboard and link research results with projects, ' +
'communities and other research projects.';
if(!community.isPublic()) {
this.inviteDisableMessage = "Community's status is " + (community.isRestricted()?'Visible to managers':'Hidden') + " and invitation to join the Research community dashboard is disabled. Update the community status to enable invitations."
}
this.loading = false;
}
@ -52,4 +61,8 @@ export class UsersSubscribersComponent implements OnInit {
}
});
}
private getURL(id: string): string {
return 'https://' + (properties.environment !== "production"?'beta.':'') + id + ".openaire.eu?verify=";
}
}

@ -5,11 +5,12 @@ import {LoadingModule} from "../../../openaireLibrary/utils/loading/loading.modu
import {RouterModule} from "@angular/router";
import {SubscribersModule} from "../../../openaireLibrary/dashboard/users/subscribers/subscribers.module";
import {UsersTabsModule} from '../users-tabs.module';
import {RoleUsersModule} from "../../../openaireLibrary/dashboard/users/role-users/role-users.module";
@NgModule({
imports: [CommonModule, LoadingModule, RouterModule.forChild([
{path: '', component: UsersSubscribersComponent}
]), SubscribersModule, UsersTabsModule],
]), SubscribersModule, UsersTabsModule, RoleUsersModule],
declarations: [UsersSubscribersComponent],
exports: [UsersSubscribersComponent]
})

@ -194,7 +194,7 @@ export class AddZenodoCommunitiesComponent implements OnInit {
public getOpenaireId(community: any): string {
for (let com of this.selectedCommunities) {
if (com.id == community.id) {
return com.openaireId;
return com.id;
}
}
return null;

@ -1,16 +1,6 @@
<div page-content>
<div header>
<div class="uk-flex uk-flex-middle uk-margin-medium-top info">
<div>
<div class="uk-text-background uk-text-bold uk-text-small">Admin Dashboard - Manage Zenodo Communities
</div>
<h1 class="uk-h6 uk-margin-remove">{{community.shortTitle}}</h1>
</div>
</div>
<community-info tab="zenodo-communities"></community-info>
</div>
<div actions>
<div class="uk-section-xsmall">
<div class="uk-section-xsmall uk-margin-top">
<div class="uk-flex uk-flex-right@m uk-flex-center uk-flex-middle uk-grid" uk-grid>
<div search-input [expandable]="true" [searchControl]="filterForm" searchInputClass="outer"
placeholder="Search Zenodo Community" [disabled]="searchUtils.status === errorCodes.LOADING"

@ -88,7 +88,7 @@ export class ManageZenodoCommunitiesComponent implements OnInit, OnDestroy {
}
public confirmedDeleteCommunity(data: any) {
this.subscriptions.push(this._manageZenodoCommunitiesService.removeZCommunity(this.properties, this.community.communityId, this.selectedToDelete.openaireId).subscribe(
this.subscriptions.push(this._manageZenodoCommunitiesService.removeZCommunity(this.properties, this.community.communityId, this.selectedToDelete.id).subscribe(
data => {
var pos = -1;
for (var i = 0; i < this.selectedCommunities.length; i++) {

@ -3,8 +3,6 @@ import {ActivatedRoute, Router} from '@angular/router';
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties';
import {ZenodoCommunitiesService} from '../../openaireLibrary/connect/zenodoCommunities/zenodo-communities.service';
import {SearchZenodoCommunitiesService} from '../../openaireLibrary/connect/zenodoCommunities/searchZenodoCommunities.service';
import {CommunityService} from '../../openaireLibrary/connect/community/community.service';
import {CommunityInfo} from '../../openaireLibrary/connect/community/communityInfo';
import {ZenodoCommunityInfo} from '../../openaireLibrary/connect/zenodoCommunities/zenodoCommunityInfo';
@ -50,8 +48,7 @@ export class ZenodoCommunitiesComponent implements OnInit, OnDestroy {
constructor(private element: ElementRef, private route: ActivatedRoute, private _router: Router,
private _zenodoCommunitieService: ZenodoCommunitiesService, private title: Title,
private _communityService: CommunityService,
private _searchZenodoCommunitiesService: SearchZenodoCommunitiesService) {
private _communityService: CommunityService) {
}
ngOnInit() {
@ -65,8 +62,7 @@ export class ZenodoCommunitiesComponent implements OnInit, OnDestroy {
this.masterZenodoCommunityId = this.community.zenodoCommunity;
if (this.masterZenodoCommunityId) {
this.subscriptions.push(this._zenodoCommunitieService.getZenodoCommunityById(this.properties,
this.properties.zenodoCommunities + this.masterZenodoCommunityId,
null).subscribe(
this.masterZenodoCommunityId).subscribe(
result => {
this.masterZenodoCommunity = result;
this.selectedCommunities.unshift(this.masterZenodoCommunity);
@ -81,25 +77,24 @@ export class ZenodoCommunitiesComponent implements OnInit, OnDestroy {
}
this.zenodoSearchUtils.status = this.errorCodes.LOADING;
this.zenodoSearchUtils.status = this.errorCodes.LOADING;
this._searchZenodoCommunitiesService.searchZCommunities(this.properties, this.community.communityId).subscribe(
result => {
this.selectedCommunityIds = result;
// this._searchZenodoCommunitiesService.searchZCommunities(this.properties, this.community.communityId).subscribe(
// result => {
this.selectedCommunityIds = this.community.otherZenodoCommunities;
this.zenodoSearchUtils.totalResults = this.selectedCommunityIds.length;
if (this.selectedCommunityIds.length === 0) {
this.zenodoSearchUtils.status = this.errorCodes.NONE;
}
for (let i = 0; i < this.selectedCommunityIds.length; i++) {
this.getZenodoCommunityById(
this.selectedCommunityIds[i]['zenodoid'],
this.selectedCommunityIds[i]['id']);
this.selectedCommunityIds[i]);
}
},
error => {
console.log('list of zenodo communities couldn\'t be loaded');
this.zenodoSearchUtils.status = this.errorCodes.DONE;
}
);
// },
// error => {
// console.log('list of zenodo communities couldn\'t be loaded');
// this.zenodoSearchUtils.status = this.errorCodes.DONE;
// }
// );
})
);
@ -116,9 +111,9 @@ export class ZenodoCommunitiesComponent implements OnInit, OnDestroy {
});
}
getZenodoCommunityById(zenodoid, openaireId) {
getZenodoCommunityById(zenodoid) {
this.subscriptions.push(this._zenodoCommunitieService.getZenodoCommunityById(this.properties,
this.properties.zenodoCommunities + zenodoid, openaireId).subscribe(
zenodoid).subscribe(
result => {
this.selectedCommunities.push(result);
this.zenodocommunitiesloadedCount++;
@ -131,7 +126,6 @@ export class ZenodoCommunitiesComponent implements OnInit, OnDestroy {
error => {
const emptyCommunity: ZenodoCommunityInfo = new ZenodoCommunityInfo();
emptyCommunity.id = zenodoid;
emptyCommunity.openaireId = openaireId;
emptyCommunity.title = zenodoid;
this.selectedCommunities.push(emptyCommunity);
this.zenodocommunitiesloadedCount++;

@ -5,12 +5,10 @@ import {RouterModule} from '@angular/router';
import {ManageZenodoCommunitiesComponent} from './manage-zenodo-communities.component';
import {AddZenodoCommunitiesComponent} from './add-zenodo-communities.component';
import {ZenodoCommunitiesComponent} from './zenodo-communities.component';
import {SearchZenodoCommunitiesServiceModule} from '../../openaireLibrary/connect/zenodoCommunities/searchZenodoCommunitiesService.module';
import {ManageZenodoCommunitiesService} from '../../services/manageZenodoCommunities.service';
import {ZenodoCommunitiesServiceModule} from '../../openaireLibrary/connect/zenodoCommunities/zenodo-communitiesService.module';
import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.module';
import {ZenodoCommunitiesRoutingModule} from './zenodo-communities-routing.module';
import {CommunityInfoModule} from '../community-info/community-info.module';
import {SearchInputModule} from '../../openaireLibrary/sharedComponents/search-input/search-input.module';
import {IconsModule} from '../../openaireLibrary/utils/icons/icons.module';
import {NoLoadPaging} from '../../openaireLibrary/searchPages/searchUtils/no-load-paging.module';
@ -23,8 +21,8 @@ import {PagingModule} from "../../openaireLibrary/utils/paging.module";
@NgModule({
imports: [
CommonModule, FormsModule, RouterModule, SearchZenodoCommunitiesServiceModule, ZenodoCommunitiesServiceModule,
AlertModalModule, ZenodoCommunitiesRoutingModule, CommunityInfoModule, PageContentModule, SearchInputModule, IconsModule, NoLoadPaging, LoadingModule, FullScreenModalModule, HTMLToStringPipeModule, PagingModule
CommonModule, FormsModule, RouterModule, ZenodoCommunitiesServiceModule,
AlertModalModule, ZenodoCommunitiesRoutingModule, PageContentModule, SearchInputModule, IconsModule, NoLoadPaging, LoadingModule, FullScreenModalModule, HTMLToStringPipeModule, PagingModule
],
declarations: [
ManageZenodoCommunitiesComponent, ZenodoCommunitiesComponent, AddZenodoCommunitiesComponent, PreviewZenodoCommunityComponent

@ -11,7 +11,7 @@ export class ManageCommunityContentProvidersService {
removeContentProvider(properties: EnvProperties, pid: string, id: string): any {
let headers = new HttpHeaders({'Content-Type': 'application/json', 'accept': 'application/json'});
let url = properties.communityAPI + pid + '/contentproviders';
let url = properties.communityAPI + pid + '/contentproviders?contentproviderId=' +id;
return this.http.request('delete', url, {body: id, headers: headers});
}

@ -12,9 +12,9 @@ export class ManageCommunityProjectsService {
let headers = new HttpHeaders({'Content-Type': 'application/json', 'accept': 'application/json'});
let url = properties.communityAPI+pid+"/projects";
let url = properties.communityAPI+pid+"/projects?projectId="+id;
//return this.http.delete(url, options)
return this.http.request('delete', url, { body: id, headers: headers})
return this.http.request('delete', url, { headers: headers})
}
addProject(properties:EnvProperties, pid: string, project: any) {

@ -11,10 +11,10 @@ export class ManageZenodoCommunitiesService {
//let options = new RequestOptions({headers: headers, body: id});
let headers = new HttpHeaders({'Content-Type': 'application/json', 'accept': 'application/json'});
let url = properties.communityAPI + pid + "/zenodocommunities";
let url = properties.communityAPI + pid + "/zenodocommunities?zenodocommunity="+id;
//return this.http.delete(url, options);
return this.http.request('delete', url, { body: id, headers: headers})
return this.http.request('delete', url, { headers: headers})
}
addZCommunity(properties:EnvProperties, pid: string,zenodoid: string) {
@ -23,13 +23,9 @@ export class ManageZenodoCommunitiesService {
let headers = new HttpHeaders({'Content-Type': 'application/json'});
let url = properties.communityAPI+pid+"/zenodocommunities";
var zCommunity: any = {
"communityId": pid,
let url = properties.communityAPI+pid+"/zenodocommunities?zenodocommunity="+zenodoid;
"zenodoid": zenodoid
};
return this.http.post<any>(url, JSON.stringify(zCommunity), {headers: headers});
return this.http.post<any>(url, headers);
//.map(res => <any> res.json())
}

@ -1 +1 @@
Subproject commit 658d017b02df4786e9b221f51eb39ef9a42c6d88
Subproject commit 3b437aafda7a716a0a89785a106456cbe520dce3

@ -1 +1 @@
Subproject commit fb1d7149654415dd6b848b86ab5187401f50975e
Subproject commit 99ab54cdd7b973a2ba047f0a6b37667270b58439

@ -1,91 +1,14 @@
import {EnvProperties} from '../app/openaireLibrary/utils/properties/env-properties';
import {common, commonBeta, commonProd} from "../app/openaireLibrary/utils/properties/environments/environment";
export let properties: EnvProperties = {
environment: "beta",
dashboard: 'connect',
let props: EnvProperties = {
isDashboard: true,
adminToolsPortalType: "community",
enablePiwikTrack: false,
useCache: false,
framesAPIURL: "https://beta.openaire.eu/stats3/",
claimsAPIURL: "https://beta.services.openaire.eu/claims/rest/claimsService/",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsFrameAPIURL: "https://beta.openaire.eu/stats/",
statisticsFrameNewAPIURL: "https://stats.madgik.di.uoa.gr/stats-api/",
useNewStatistisTool: true,
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/",
orcidURL: "https://orcid.org/",
doiURL: "https://dx.doi.org/",
cordisURL: "http://cordis.europa.eu/projects/",
openDoarURL: "http://v2.sherpa.ac.uk/id/repository/",
r3DataURL: "http://service.re3data.org/repository/",
sherpaURL: "http://www.sherpa.ac.uk/romeo/search.php?issn=",
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=6",
registryUrl: 'https://beta.services.openaire.eu/uoa-user-management/api/registry/',
loginUrl: "https://beta.services.openaire.eu/login-service/openid_connect_login",
userInfoUrl: "https://beta.services.openaire.eu/login-service/userInfo",
logoutUrl: "https://beta.services.openaire.eu/login-service/openid_logout",
cookieDomain: ".openaire.eu",
feedbackmail: "feedback@openaire.eu",
feedbackmailForMissingEntities: "feedback@openaire.eu",
cacheUrl: "https://demo.openaire.eu/cache/get?url=",
deleteCacheUrl: 'https://demo.openaire.eu/cache/clear',
deleteBrowserCacheUrl: 'https://beta.services.openaire.eu/uoa-admin-tools/cache',
adminToolsAPIURL: "https://beta.services.openaire.eu/uoa-admin-tools/",
adminToolsCommunity: "openaire",
communityAPI: "https://beta.services.openaire.eu/openaire/community/",
miningBackendURL: "https://beta.services.openaire.eu/interactive-mining",
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
baseLink: "",
domain: "https://beta.admin.connect.openaire.eu/",
baseOpenaireLink: "https://beta.explore.openaire.eu",
searchLinkToPublication: "/search/publication?articleId=",
searchLinkToProject: "/search/project?projectId=",
searchLinkToDataProvider: "/search/dataprovider?datasourceId=",
searchLinkToDataset: "/search/dataset?datasetId=",
searchLinkToOrganization: "/search/organization?organizationId=",
searchLinkToPublications: "/search/find/publications",
searchLinkToDataProviders: "/search/find/dataproviders",
searchLinkToProjects: "/search/find/projects",
searchLinkToDatasets: "/search/find/datasets",
searchLinkToSoftware: "/search/find/software",
searchLinkToOrganizations: "/search/find/organizations",
searchLinkToCompatibleDataProviders: "/search/content-providers",
searchLinkToEntityRegistriesDataProviders: "/search/entity-registries",
searchLinkToJournals: "/search/journals",
searchLinkToAdvancedPublications: "/search/advanced/publications",
searchLinkToAdvancedProjects: "/search/advanced/projects",
searchLinkToAdvancedDatasets: "/search/advanced/datasets",
searchLinkToAdvancedSoftware: "/search/advanced/software",
searchLinkToAdvancedDataProviders: "/search/advanced/dataproviders",
searchLinkToAdvancedOrganizations: "/search/advanced/organizations",
lastIndexInformationLink: "https://beta.openaire.eu/aggregation-and-content-provision-workflows",
showLastIndexInformationLink: false,
widgetLink: "https://beta.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
claimsInformationLink: "https://beta.openaire.eu/linking",
lastIndexUpdate: "2020-05-06",
indexInfoAPI: "https://beta.services.openaire.eu/openaire/info/",
admins: ["rcd@openaire.eu"],
adminPortalURL: "https://beta.admin.connect.openaire.eu",
errorLink: '/error',
connectPortalUrl: 'https://beta.connect.openaire.eu'
domain:'https://beta.admin.connect.openaire.eu'
};
export let properties: EnvProperties = {
...common, ...commonBeta, ...props
}

@ -1,91 +1,15 @@
import {EnvProperties} from '../app/openaireLibrary/utils/properties/env-properties';
import {common, commonProd} from "../app/openaireLibrary/utils/properties/environments/environment";
let props: EnvProperties = {
export let properties: EnvProperties = {
environment:"production",
dashboard: 'connect',
isDashboard: true,
adminToolsPortalType: "community",
enablePiwikTrack: false,
useCache: false,
framesAPIURL: "https://www.openaire.eu/stats3/",
claimsAPIURL: "https://services.openaire.eu/claims/rest/claimsService/",
statisticsAPIURL: "https://beta.services.openaire.eu/stats-api/",
statisticsFrameAPIURL:"https://www.openaire.eu/stats/",
statisticsFrameNewAPIURL: "http://marilyn.athenarc.gr:8080/stats-api/",
useNewStatistisTool:false,
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/",
orcidURL: "https://orcid.org/",
doiURL: "https://dx.doi.org/",
cordisURL: "http://cordis.europa.eu/projects/",
openDoarURL: "http://v2.sherpa.ac.uk/id/repository/",
r3DataURL: "http://service.re3data.org/repository/",
sherpaURL: "http://www.sherpa.ac.uk/romeo/search.php?issn=",
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=6",
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:"openaire.test@gmail.com",
feedbackmailForMissingEntities: "feedback@openaire.eu",
cacheUrl:"https://explore.openaire.eu/cache/get?url=",
deleteCacheUrl: 'https://explore.openaire.eu/cache/clear',
deleteBrowserCacheUrl: 'https://services.openaire.eu/uoa-admin-tools/cache',
adminToolsAPIURL:"https://services.openaire.eu/uoa-admin-tools/",
adminToolsCommunity:"openaire",
communityAPI: "https://services.openaire.eu/openaire/community/",
miningBackendURL: "https://beta.services.openaire.eu/interactive-mining",
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
baseLink: "",
domain: "https://admin.explore.openaire.eu/",
baseOpenaireLink: "https://explore.openaire.eu",
searchLinkToPublication: "/search/publication?articleId=",
searchLinkToProject: "/search/project?projectId=",
searchLinkToDataProvider: "/search/dataprovider?datasourceId=",
searchLinkToDataset: "/search/dataset?datasetId=",
searchLinkToOrganization: "/search/organization?organizationId=",
searchLinkToPublications: "/search/find/publications",
searchLinkToDataProviders: "/search/find/dataproviders",
searchLinkToProjects: "/search/find/projects",
searchLinkToDatasets: "/search/find/datasets",
searchLinkToSoftware: "/search/find/software",
searchLinkToOrganizations: "/search/find/organizations",
searchLinkToCompatibleDataProviders: "/search/content-providers",
searchLinkToEntityRegistriesDataProviders: "/search/entity-registries",
searchLinkToJournals: "/search/journals",
searchLinkToAdvancedPublications: "/search/advanced/publications",
searchLinkToAdvancedProjects: "/search/advanced/projects",
searchLinkToAdvancedDatasets: "/search/advanced/datasets",
searchLinkToAdvancedSoftware: "/search/advanced/software",
searchLinkToAdvancedDataProviders: "/search/advanced/dataproviders",
searchLinkToAdvancedOrganizations: "/search/advanced/organizations",
lastIndexInformationLink: "https://www.openaire.eu/aggregation-and-content-provision-workflows",
showLastIndexInformationLink: false,
widgetLink: "https://www.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=",
claimsInformationLink: "https://www.openaire.eu/linking",
lastIndexUpdate: "2020-12-17",
indexInfoAPI: "https://services.openaire.eu/openaire/info/",
admins: ["rcd@openaire.eu"],
adminPortalURL: "https://admin.connect.openaire.eu",
errorLink: '/error',
connectPortalUrl: 'https://connect.openaire.eu'
domain:'https://admin.connect.openaire.eu',
};
export let properties: EnvProperties = {
...common, ...commonProd, ...props
}

@ -4,93 +4,19 @@
// 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, commonProd} from "../app/openaireLibrary/utils/properties/environments/environment";
let props: EnvProperties = {
export let properties: EnvProperties = {
environment: 'development',
dashboard: 'connect',
isDashboard: true,
adminToolsPortalType: "community",
enablePiwikTrack: false,
useCache: false,
framesAPIURL: 'https://beta.openaire.eu/stats3/',
claimsAPIURL: 'http://scoobydoo.di.uoa.gr:8080/dnet-claims-service-2.0.0-SNAPSHOT/rest/claimsService/',
statisticsAPIURL: 'https://beta.services.openaire.eu/stats-api/',
statisticsFrameAPIURL: 'https://beta.openaire.eu/stats/',
statisticsFrameNewAPIURL: "https://stats.madgik.di.uoa.gr/stats-api/",
useNewStatistisTool: true,
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/',
orcidURL: 'https://orcid.org/',
doiURL: 'https://dx.doi.org/',
cordisURL: 'http://cordis.europa.eu/projects/',
openDoarURL: 'http://v2.sherpa.ac.uk/id/repository/',
r3DataURL: 'http://service.re3data.org/repository/',
sherpaURL: 'http://www.sherpa.ac.uk/romeo/search.php?issn=',
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://beta.services.openaire.eu/provision/mvc/vocabularies/',
piwikBaseUrl: ' https://analytics.openaire.eu/piwik.php?idsite=6',
registryUrl: 'http://mpagasas.di.uoa.gr:8080/dnet-openaire-users-1.0.0-SNAPSHOT/api/registry/',
loginUrl: "http://mpagasas.di.uoa.gr:19080/login-service/openid_connect_login",
userInfoUrl: "http://mpagasas.di.uoa.gr:19080/login-service/userInfo",
logoutUrl: "http://mpagasas.di.uoa.gr:19080/login-service/openid_logout",
cookieDomain: '.di.uoa.gr',
feedbackmail: 'openaire.test@gmail.com',
feedbackmailForMissingEntities: 'feedback@openaire.eu',
cacheUrl: 'http://scoobydoo.di.uoa.gr:3000/get?url=',
deleteCacheUrl: 'http://duffy.di.uoa.gr:3000/clear',
deleteBrowserCacheUrl: 'http://duffy.di.uoa.gr:19280/uoa-admin-tools/cache',
adminToolsAPIURL: 'http://duffy.di.uoa.gr:19280/uoa-admin-tools/',
adminToolsCommunity: 'openaire',
communityAPI: 'https://dev-openaire.d4science.org/openaire/community/',
miningBackendURL: 'https://beta.services.openaire.eu/interactive-mining',
csvLimit: 2000,
pagingLimit: 20,
resultsPerPage: 10,
baseLink: "",
connectPortalUrl: 'http://scoobydoo.di.uoa.gr:4200',
domain:'https://beta.admin.connect.openaire.eu',
baseOpenaireLink: 'https://beta.explore.openaire.eu',
searchLinkToPublication: '/search/publication?articleId=',
searchLinkToProject: '/search/project?projectId=',
searchLinkToDataProvider: '/search/dataprovider?datasourceId=',
searchLinkToDataset: '/search/dataset?datasetId=',
searchLinkToOrganization: '/search/organization?organizationId=',
searchLinkToPublications: '/search/find/publications',
searchLinkToDataProviders: '/search/find/dataproviders',
searchLinkToProjects: '/search/find/projects',
searchLinkToDatasets: '/search/find/datasets',
searchLinkToSoftware: '/search/find/software',
searchLinkToOrganizations: '/search/find/organizations',
searchLinkToCompatibleDataProviders: '/search/content-providers',
searchLinkToEntityRegistriesDataProviders: '/search/entity-registries',
searchLinkToJournals: '/search/journals',
searchLinkToAdvancedPublications: '/search/advanced/publications',
searchLinkToAdvancedProjects: '/search/advanced/projects',
searchLinkToAdvancedDatasets: '/search/advanced/datasets',
searchLinkToAdvancedSoftware: '/search/advanced/software',
searchLinkToAdvancedDataProviders: '/search/advanced/dataproviders',
searchLinkToAdvancedOrganizations: '/search/advanced/organizations',
lastIndexInformationLink: 'https://www.openaire.eu/aggregation-and-content-provision-workflows',
showLastIndexInformationLink: false,
widgetLink: 'https://beta.openaire.eu/index.php?option=com_openaire&view=widget&format=raw&projectId=',
claimsInformationLink: 'https://www.openaire.eu/linking-beta',
lastIndexUpdate: '2019-05-16',
indexInfoAPI: 'http://beta.services.openaire.eu/openaire/info/',
admins: ['kostis30fylloy@gmail.com'],
adminPortalURL: 'https://beta.admin.connect.openaire.eu',
errorLink: '/error',
connectPortalUrl: 'http://scoobydoo.di.uoa.gr:4200'
};
export let properties: EnvProperties = {
...common, ...commonDev, ...props
}

@ -1,5 +1,5 @@
@use "sass:meta";
@import "~interactiveminingv3/assets/css/variables.css";
@import "node_modules/interactiveminingv3/assets/css/variables.css";
.mining {

@ -7,8 +7,6 @@ import {
platformBrowserDynamicTesting
} from '@angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
@ -16,7 +14,3 @@ getTestBed().initTestEnvironment(
teardown: { destroyAfterEach: false }
}
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

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

Loading…
Cancel
Save