diff --git a/claims/claim-utils/claimContextSearchForm.component.ts b/claims/claim-utils/claimContextSearchForm.component.ts index 463c9d93..614d1d09 100644 --- a/claims/claim-utils/claimContextSearchForm.component.ts +++ b/claims/claim-utils/claimContextSearchForm.component.ts @@ -6,6 +6,7 @@ import {EnvProperties} from '../../utils/properties/env-properties'; import {Subscriber} from "rxjs"; import {OpenaireEntities} from "../../utils/properties/searchFields"; import {CommunitiesService} from "../../connect/communities/communities.service"; +import {UserManagementService} from "../../services/user-management.service"; declare var UIkit: any; @@ -46,9 +47,14 @@ export class ClaimContextSearchFormComponent { keyword = ""; subscriptions = []; communityLogos = {}; + communityIds = []; + user = null; ngOnInit() { this.entitiesSelectOptions = this.showOptions.selectOptions; //get community logos + this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { + this.user = user; + this.subscriptions.push(this._communitiesService.getCommunities(this.properties, this.properties.communityAPI+"/communities/").subscribe( communitiesResults => { if(communitiesResults!=null) { @@ -58,6 +64,13 @@ export class ClaimContextSearchFormComponent { this.communityLogos[community.communityId] = community; } } + this.communityIds = communitiesResults.filter(community => { + return community.claim == "all" || + Session.isCommunityCurator(this.user) || + Session.isClaimsCurator(this.user) || + (community.claim == "membersOnly" && Session.isSubscribedTo("community", community.communityId,this.user)) || + (community.claim == "managersOnly" && Session.isManager("community", community.communityId,this.user)) + }).map(community => community.communityId); this.getCommunities(); } }, @@ -65,6 +78,10 @@ export class ClaimContextSearchFormComponent { this.getCommunities(); } )); + + }, error => { + + })); } ngOnDestroy() { @@ -74,7 +91,7 @@ export class ClaimContextSearchFormComponent { } }); } - constructor(private _contextService: ContextsService, private router: Router, private _communitiesService: CommunitiesService) { + constructor(private _contextService: ContextsService, private router: Router, private _communitiesService: CommunitiesService, private userManagementService: UserManagementService,) { } @@ -165,15 +182,16 @@ export class ClaimContextSearchFormComponent { getCommunities() { this.loading = true; - this.subscriptions.push(this._contextService.getPublicCommunitiesByState().subscribe( + this.subscriptions.push(this._contextService.getCommunitiesByState().subscribe( data => { - this.communities = data; - console.log(this.communities) + this.communities = data.filter(community => { + return this.communityIds.indexOf(community.id) != -1 + }); if (this.communities.length > 0) { - this.communities.sort((n1, n2) => n1.label > n2.label); + this.communities.sort((n1, n2) => n1.title > n2.title); } this.loading = false; - if (this.communityId != null) { + if (this.communityId != null && this.communityIds.indexOf(this.communityId) != -1) { //preselect community this.selectedCommunityId = this.communityId; for (let i = 0; i < this.communities.length; i++) { diff --git a/connect/communities/communities.service.ts b/connect/communities/communities.service.ts index 299cfe32..05f427a6 100644 --- a/connect/communities/communities.service.ts +++ b/connect/communities/communities.service.ts @@ -56,12 +56,11 @@ export class CommunitiesService { result['description'] = resData.description; result['date'] = resData.creationDate; result['status'] = 'all'; + result['claim'] = resData.claim; + result['membership'] = resData.membership; if (resData.hasOwnProperty('status')) { result['status'] = resData.status; - const status = ['all', 'hidden', 'manager']; - if (status.indexOf(result['status']) === -1) { - result['status'] = 'hidden'; - } + result.validateStatus(); } if (resData.type != null) { result['type'] = resData.type; diff --git a/connect/community/community.service.ts b/connect/community/community.service.ts index d8fe6975..06d222e0 100644 --- a/connect/community/community.service.ts +++ b/connect/community/community.service.ts @@ -98,14 +98,14 @@ export class CommunityService { community.description = resData.description; community.date = resData.creationDate; community.zenodoCommunity = resData.zenodoCommunity; - community.status = 'all'; + community.status = 'PUBLIC'; + community.claim = resData.claim; + community.membership = resData.membership; community.type = resData.type; + community.otherZenodoCommunities = resData.otherZenodoCommunities; if (resData.hasOwnProperty('status')) { community.status = resData.status; - const status = ['all', 'hidden', 'manager']; - if (status.indexOf(community['status']) === -1) { - community.status = 'hidden'; - } + community.validateStatus(); } if (resData.subjects != null) { community.subjects = Array.isArray(resData.subjects)?resData.subjects:[resData.subjects]; diff --git a/connect/community/communityInfo.ts b/connect/community/communityInfo.ts index 231a642d..8a8469ce 100644 --- a/connect/community/communityInfo.ts +++ b/connect/community/communityInfo.ts @@ -1,5 +1,4 @@ import {StringUtils} from "../../utils/string-utils.class"; -import {properties} from "../../../../environments/environment"; import {SelectionCriteria} from "../../utils/entities/contentProvider"; export class CommunityInfo { @@ -14,8 +13,11 @@ export class CommunityInfo { managers: string[]; date:Date; subjects: string[]; - status:string; + status:"all" | "manager" | "hidden" | "PUBLIC" | "RESTRICTED" | "PRIVATE"; + claim: "all" | "managersOnly" | "membersOnly"; + membership: "open" | "byInvitation"; zenodoCommunity:string; + otherZenodoCommunities: string[]; isUpload: boolean; isSubscribed: boolean; isManager: boolean; @@ -33,5 +35,24 @@ export class CommunityInfo { } return response; } + + public isOpen() { + return !(this.membership && this.membership === 'byInvitation'); + } + + public isPublic(){ + return this.status == "all" || this.status == "PUBLIC"; + } + public isRestricted(){ + return this.status == "manager" || this.status == "RESTRICTED"; + } + public isPrivate(){ + return this.status == "hidden" || this.status == "PRIVATE"; + } + public validateStatus(){ + if(!(this.isPrivate() || this.isRestricted() || this.isPublic())){ + this.status = "PRIVATE"; + } + } } // export const prodReadyCommunities = ["dh-ch", "ee", "fam", "mes", "ni", "covid-19", "dariah", "epos", "egi"]; diff --git a/connect/connectHelper.ts b/connect/connectHelper.ts index 1fbbc59a..d53a63a3 100644 --- a/connect/connectHelper.ts +++ b/connect/connectHelper.ts @@ -1,6 +1,7 @@ import {HttpParams} from '@angular/common/http'; import {properties} from "../../../environments/environment"; import {Session} from "../login/utils/helper.class"; +import {CommunityInfo} from "./community/communityInfo"; export class ConnectHelper { @@ -53,7 +54,12 @@ export class ConnectHelper { } - public static isPrivate(community, user) { - return community && (community.status == "hidden" || (community.status == "manager" && !(Session.isPortalAdministrator(user) || Session.isCommunityCurator(user) || Session.isManager("community", community.communityId, user)))) + public static isPrivate(community: CommunityInfo, user) { + return community && (community.isPrivate() || (community.isRestricted() && !( + Session.isPortalAdministrator(user) || + Session.isCommunityCurator(user) || + Session.isManager("community", community.communityId, user) || + (!community.isOpen() && Session.isMember('community', community.communityId, user)) + ))) } } diff --git a/connect/projects/searchProjects.service.ts b/connect/projects/searchProjects.service.ts index c580d190..e86fd1a8 100644 --- a/connect/projects/searchProjects.service.ts +++ b/connect/projects/searchProjects.service.ts @@ -7,15 +7,25 @@ import {map} from "rxjs/operators"; export class SearchCommunityProjectsService { constructor(private http: HttpClient ) {} - searchProjects (properties:EnvProperties, pid: string):any { - let url = properties.communityAPI+pid+"/projects"; - + searchProjects (properties:EnvProperties, pid: string, page=1, size=500):any { + return this.searchProjectsWithPaging(properties,pid,page, size, null, null); + } + searchProjectsWithPaging (properties:EnvProperties, pid: string, page=1, size=500, searchFilter, funder, orderBy = "name"):any { + let params = funder ? ["funder="+ funder] :[]; + if (searchFilter) { + params.push("searchFilter="+ searchFilter) + } + params.push("orderBy="+ orderBy); + let url = properties.communityAPI+pid+"/projects/"+ (page-1) + "/" + size + (params.length > 0?"?" + params.join("&"):""); return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url); - //.map(res => res.json()) } countTotalProjects(properties:EnvProperties,pid:string) { - let url = properties.communityAPI+pid+"/projects"; + let url = properties.communityAPI+pid+"/projects/0/1"; return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url) - .pipe(map(res => res['length'])); + .pipe(map(res => res['totalElements'])); + } + getProjectFunders(properties:EnvProperties,pid:string) { + let url = properties.communityAPI+pid+"/funders"; + return this.http.get((properties.useCache) ? (properties.cacheUrl + encodeURIComponent(url)) : url); } } diff --git a/connect/zenodoCommunities/searchZenodoCommunities.service.ts b/connect/zenodoCommunities/searchZenodoCommunities.service.ts deleted file mode 100644 index 02fb8fda..00000000 --- a/connect/zenodoCommunities/searchZenodoCommunities.service.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {Injectable} from '@angular/core'; -import {HttpClient} from "@angular/common/http"; -import{EnvProperties} from '../../utils/properties/env-properties'; - -@Injectable() -export class SearchZenodoCommunitiesService { - constructor(private http: HttpClient ) {} - - searchZCommunities (properties:EnvProperties, pid: string):any { - let url = properties.communityAPI+pid+"/zenodocommunities"; - - return this.http.get((properties.useCache)? (properties.cacheUrl+encodeURIComponent(url)): url); - //.map(res => res.json()) - } -} diff --git a/connect/zenodoCommunities/searchZenodoCommunitiesService.module.ts b/connect/zenodoCommunities/searchZenodoCommunitiesService.module.ts deleted file mode 100644 index 704bfe82..00000000 --- a/connect/zenodoCommunities/searchZenodoCommunitiesService.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { NgModule} from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; - -import {SearchZenodoCommunitiesService} from './searchZenodoCommunities.service'; - - - -@NgModule({ - imports: [ - CommonModule, FormsModule - ], - declarations: [ - ], - providers:[ - SearchZenodoCommunitiesService -], - exports: [ - ] -}) -export class SearchZenodoCommunitiesServiceModule { } diff --git a/connect/zenodoCommunities/zenodo-communities.service.ts b/connect/zenodoCommunities/zenodo-communities.service.ts index bf790f27..5268a079 100644 --- a/connect/zenodoCommunities/zenodo-communities.service.ts +++ b/connect/zenodoCommunities/zenodo-communities.service.ts @@ -16,12 +16,11 @@ export class ZenodoCommunitiesService { //.map(res => res.json()) .pipe(map(res => [this.parseZenodoCommunities(res['hits'].hits),res['hits'].total])); } - getZenodoCommunityById(properties:EnvProperties, url: string, openaireId:string) { + getZenodoCommunityById(properties:EnvProperties, url: string) { return this.http.get((properties.useLongCache)? (properties.cacheUrl+encodeURIComponent(url)) : url) //.map(res => res.json()) .pipe(map(res => { var community = this.parseZenodoCommunity(res); - community["openaireId"]=openaireId; return community; })); } diff --git a/connect/zenodoCommunities/zenodoCommunityInfo.ts b/connect/zenodoCommunities/zenodoCommunityInfo.ts index 491bec39..5fb7df3f 100644 --- a/connect/zenodoCommunities/zenodoCommunityInfo.ts +++ b/connect/zenodoCommunities/zenodoCommunityInfo.ts @@ -6,5 +6,4 @@ export class ZenodoCommunityInfo { logoUrl: string; date: Date; page: string; - openaireId:string; } diff --git a/fos/fos.component.ts b/fos/fos.component.ts index c02b6bed..043e7bd5 100644 --- a/fos/fos.component.ts +++ b/fos/fos.component.ts @@ -216,6 +216,7 @@ export class FosComponent implements OnInit, OnDestroy { } public buildFosQueryParam(fos) { - return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}; + // return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}; + return (properties.environment !== 'production' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)})); } } diff --git a/landingPages/landing-utils/availableOn.component.ts b/landingPages/landing-utils/availableOn.component.ts index 9a1d217c..23c8ef1e 100644 --- a/landingPages/landing-utils/availableOn.component.ts +++ b/landingPages/landing-utils/availableOn.component.ts @@ -11,44 +11,59 @@ import {RouterHelper} from "../../utils/routerHelper.class"; selector: 'availableOn', template: ` -
- - - - - - - {{sliceString(availableOn[0].downloadNames.join("; "), 20)}} - - - - - -
- -
-
- - - - {{sliceString(availableOn[0].downloadNames.join("; "), 20)}} - - +
+ +

+ @@ -79,6 +94,14 @@ import {RouterHelper} from "../../utils/routerHelper.class"; {{instance.license}}
+
+ Full-Text: + + {{instance.fulltext}} + + {{instance.fulltext}} +
Data sources: `; + bibtex:string =``; ieee:string =` `; chicago:string =` `; science:string =' '; diff --git a/landingPages/landing-utils/entity-metadata.component.ts b/landingPages/landing-utils/entity-metadata.component.ts index c15f50e0..caad8627 100644 --- a/landingPages/landing-utils/entity-metadata.component.ts +++ b/landingPages/landing-utils/entity-metadata.component.ts @@ -1,4 +1,4 @@ -import {Component, Input} from "@angular/core"; +import {Component, Input, ViewChild} from "@angular/core"; import {EnvProperties} from "../../utils/properties/env-properties"; import {properties} from "../../../../environments/environment"; import {OpenaireEntities} from "../../utils/properties/searchFields"; @@ -60,10 +60,10 @@ import {RouterHelper} from "../../utils/routerHelper.class"; {{year}} - {{startYear}} + From {{startYear}} - {{endYear}} + Until {{endYear}} @@ -151,12 +151,32 @@ import {RouterHelper} from "../../utils/routerHelper.class"; Thematic - - {{projectNames.slice(0,3).join(', ')}} + + {{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}} + + + +{{projects.length - projectsLimit | number}} projects + + + View less + + - - {{organizationNames.slice(0, 3).join(', ')}} + + {{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}} + + + +{{organizations.length - organizationsLimit | number}} partners + + + View less + + @@ -169,10 +189,37 @@ import {RouterHelper} from "../../utils/routerHelper.class"; {{relationName}}
+ + + + +
+ +
+ {{item.name}}{{i == organizations.length - 1 ? '' : ','}} +
+
+
+
+ + +
+ +
+ {{item['funderShortname'] ? item['funderShortname'] : item['funderName']}} + [no funder available] + | {{ item['acronym'] ? item['acronym'] : item['title']}} + {{i == projects.length - 1 ? '' : ','}} +
+
+
+
`, styleUrls: ['entity-metadata.component.less'] }) export class EntityMetadataComponent { + @Input() isMobile: boolean = false; @Input() entityType: string; @Input() types: string[]; @Input() year: string; // search result @@ -204,6 +251,14 @@ export class EntityMetadataComponent { @Input() subjects: string[]; @Input() prevPath: string = ""; + @ViewChild('partnersModal') partnersModal; + @ViewChild('projectsModal') projectsModal; + + organizationsLimit: number = 5; + projectsLimit: number = 3; + showInline: boolean = false; + lessBtn: boolean = false; + properties: EnvProperties = properties; public openaireEntities = OpenaireEntities; public routerHelper: RouterHelper = new RouterHelper(); @@ -260,4 +315,48 @@ export class EntityMetadataComponent { } return obj; } -} + + public viewAllPartnersClick() { + if(this.organizations.length <= this.organizationsLimit * 2) { + this.showInline = true; + this.lessBtn = true; + } else { + this.openPartnersModal(); + } + } + + public openPartnersModal() { + if (this.isMobile) { + this.partnersModal.okButton = false; + this.partnersModal.title = "Partners"; + this.partnersModal.open(); + } else { + this.partnersModal.cancelButton = false; + this.partnersModal.okButton = false; + this.partnersModal.alertTitle = "Partners"; + this.partnersModal.open(); + } + } + + public viewAllProjectsClick() { + if(this.projects.length <= this.projectsLimit * 2) { + this.showInline = true; + this.lessBtn = true; + } else { + this.openProjectsModal(); + } + } + + public openProjectsModal() { + if (this.isMobile) { + this.projectsModal.okButton = false; + this.projectsModal.title = "Projects"; + this.projectsModal.open(); + } else { + this.projectsModal.cancelButton = false; + this.projectsModal.okButton = false; + this.projectsModal.alertTitle = "Projects"; + this.projectsModal.open(); + } + } +} \ No newline at end of file diff --git a/landingPages/landing-utils/fos.component.ts b/landingPages/landing-utils/fos.component.ts index 4dfc59e6..ba95bdc8 100644 --- a/landingPages/landing-utils/fos.component.ts +++ b/landingPages/landing-utils/fos.component.ts @@ -121,10 +121,12 @@ export class FosComponent { } public buildFosQueryParam(fos) { - return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}; + // return {'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}; + return (properties.environment !== 'production' ? ({'foslabel': this.urlEncodeAndQuote(fos.id+"||"+fos.label)}) : ({'fos': this.urlEncodeAndQuote(fos.id)})); } public buildFosHrefParam(fos): string { - return ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label)); + // return ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label)); + return (properties.environment !== 'production' ? ('foslabel='+this.urlEncodeAndQuote(fos.id+"||"+fos.label)) : ('fos='+this.urlEncodeAndQuote(fos.id))); } } diff --git a/landingPages/landing-utils/parsingFunctions.class.ts b/landingPages/landing-utils/parsingFunctions.class.ts index fd2c3b12..8c40bed9 100644 --- a/landingPages/landing-utils/parsingFunctions.class.ts +++ b/landingPages/landing-utils/parsingFunctions.class.ts @@ -264,7 +264,8 @@ export class ParsingFunctions { "accessRightIcon": "", "types": [], "years": [], - "license": "" + "license": "", + "fulltext": "" }; if (instance.hasOwnProperty("hostedby")) { @@ -353,43 +354,60 @@ export class ParsingFunctions { if (instance.hasOwnProperty("license")) { available.license = Array.isArray(instance['license']) ? instance['license'][0] : instance['license']; } + + if(instance.hasOwnProperty("fulltext")) { + available.fulltext = instance['fulltext']; + } hostedBy_collectedFrom.push(available); } compareHostedByCollectedFrom(a: HostedByCollectedFrom, b: HostedByCollectedFrom) { + let retValue: number = 0; let firstAccessRight: string = (a.accessRight ? a.accessRight.toLowerCase() : null); let secondAccessRight: string = (b.accessRight ? b.accessRight.toLowerCase() : null); - - if (firstAccessRight === secondAccessRight) { - return 0; - } else { + + if (firstAccessRight !== secondAccessRight) { if (firstAccessRight === 'open access') { - return -1; + retValue = -1; } else if (secondAccessRight === 'open access') { - return 1; + retValue = 1; } else if (firstAccessRight === "open source") { - return -1; + retValue = -1; } else if (secondAccessRight === "open source") { - return 1; + retValue = 1; } else if (firstAccessRight === "embargo") { - return -1; + retValue = -1; } else if (secondAccessRight === "embargo") { - return 1; + retValue = 1; } else if (firstAccessRight === "restricted") { - return -1; + retValue = -1; } else if (secondAccessRight === "restricted") { - return 1; + retValue = 1; } else if (firstAccessRight === "closed access") { - return -1; + retValue = -1; } else if (secondAccessRight === "closed access") { - return 1; + retValue = 1; } else if (firstAccessRight === "not available") { - return -1; + retValue = -1; } else if (secondAccessRight === "not available") { - return 1; + retValue = 1; } } + + if(retValue == 0) { + let firstFulltext: string = (a.fulltext ? a.fulltext : null); + let secondFulltext: string = (b.fulltext ? b.fulltext : null); + + if (firstFulltext && !secondFulltext) { + return -1; + } else if (!firstFulltext && secondFulltext) { + return 1; + } + } else { + return retValue; + } + return 0; } @@ -514,7 +532,8 @@ export class ParsingFunctions { let identifiers = new Map(); if (pid.hasOwnProperty("classid") && pid['classid'] != "") { - if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data") { + if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data" + || pid.classid == "swhid") { if (!identifiers.has(pid.classid)) { identifiers.set(pid.classid, new Array()); } @@ -522,7 +541,8 @@ export class ParsingFunctions { } } else { for (let i = 0; i < pid.length; i++) { - if (pid[i].classid == "doi" || pid[i].classid == "pmc" || pid[i].classid == "handle" || pid[i].classid == "pmid" || pid[i].classid == "re3data") { + if (pid[i].classid == "doi" || pid[i].classid == "pmc" || pid[i].classid == "handle" || pid[i].classid == "pmid" || pid[i].classid == "re3data" + || pid[i].classid == "swhid") { if (!identifiers.has(pid[i].classid)) { identifiers.set(pid[i].classid, new Array()); } diff --git a/landingPages/landing-utils/resultLandingUtils.module.ts b/landingPages/landing-utils/resultLandingUtils.module.ts index 05869cf7..7ae62115 100644 --- a/landingPages/landing-utils/resultLandingUtils.module.ts +++ b/landingPages/landing-utils/resultLandingUtils.module.ts @@ -19,7 +19,7 @@ import {AlertModalModule} from "../../utils/modal/alertModal.module"; import { SearchInputModule } from '../../sharedComponents/search-input/search-input.module'; import {EntityMetadataComponent} from "./entity-metadata.component"; import {IconsService} from "../../utils/icons/icons.service"; -import {closed_access, open_access, unknown_access} from "../../utils/icons/icons"; +import {book, closed_access, cog, database, earth, open_access, unknown_access} from "../../utils/icons/icons"; import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module"; import {MobileDropdownModule} from "../../utils/mobile-dropdown/mobile-dropdown.module"; @@ -45,6 +45,6 @@ import {MobileDropdownModule} from "../../utils/mobile-dropdown/mobile-dropdown. }) export class ResultLandingUtilsModule { constructor(private iconsService: IconsService) { - this.iconsService.registerIcons([open_access, closed_access, unknown_access]); + this.iconsService.registerIcons([open_access, closed_access, unknown_access, book, cog, database, earth]); } } diff --git a/landingPages/landing-utils/showIdentifiers.component.ts b/landingPages/landing-utils/showIdentifiers.component.ts index e4644c34..8a0b4680 100644 --- a/landingPages/landing-utils/showIdentifiers.component.ts +++ b/landingPages/landing-utils/showIdentifiers.component.ts @@ -26,7 +26,7 @@ import {properties} from "../../../../environments/environment"; {{key}}: - {{item}} @@ -124,6 +124,8 @@ export class ShowIdentifiersComponent implements AfterViewInit { return properties.handleURL; } else if(key == "re3data") { return properties.r3DataURL; + } else if(key == "swhid") { + return properties.swhURL; } } diff --git a/landingPages/project/project.component.ts b/landingPages/project/project.component.ts index 34936cd8..4e7eb8ba 100644 --- a/landingPages/project/project.component.ts +++ b/landingPages/project/project.component.ts @@ -464,6 +464,7 @@ export class ProjectComponent { this.subscriptions.push(this._projectService.getProjectInfo(id, this.properties).subscribe( data => { this.projectInfo = data; + this.projectInfo.id = this.projectId; this.actionsAfterGettingProjectInfo(); }, diff --git a/landingPages/result/resultLanding.component.html b/landingPages/result/resultLanding.component.html index a906c918..4aa62494 100644 --- a/landingPages/result/resultLanding.component.html +++ b/landingPages/result/resultLanding.component.html @@ -611,7 +611,7 @@
-
+
- diff --git a/login/user.component.ts b/login/user.component.ts index e279b7b6..f95adf67 100644 --- a/login/user.component.ts +++ b/login/user.component.ts @@ -100,12 +100,9 @@ export class UserComponent { return formattedRoles.join(", "); } - get isCurator() { - return Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user); + get isPortalAdministrator() { + return Session.isPortalAdministrator(this.user); } - get isUserManager() { - return Session.isUserManager(this.user); - } } diff --git a/orcid/my-orcid-links/myOrcidLinks.component.ts b/orcid/my-orcid-links/myOrcidLinks.component.ts index d77e14a4..5fbe58b8 100644 --- a/orcid/my-orcid-links/myOrcidLinks.component.ts +++ b/orcid/my-orcid-links/myOrcidLinks.component.ts @@ -163,7 +163,7 @@ export class MyOrcidLinksComponent { if(typeof document !== 'undefined') { this.tokenUrl = properties.orcidTokenURL - + "clientid="+properties.orcidClientId + + "client_id=" + properties.orcidClientId // + "&response_type=code&scope=/activities/update" // + "&response_type=code&scope=/authenticate /activities/update /person/update /read-limited" + "&response_type=code&scope=/activities/update /read-limited" diff --git a/role-verification/role-verification.component.ts b/role-verification/role-verification.component.ts index 9030d636..c4a9a71a 100644 --- a/role-verification/role-verification.component.ts +++ b/role-verification/role-verification.component.ts @@ -34,7 +34,7 @@ import {ClearCacheService} from "../services/clear-cache.service";
-
@@ -119,12 +119,8 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn ngAfterViewInit() { this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.user = user; - if (this.paramsSubscription instanceof Subscription) { - this.paramsSubscription.unsubscribe(); - } this.paramsSubscription = this.route.queryParams.subscribe(params => { if (params) { - this.isMember = !!params['isMember']; this.cdr.detectChanges(); if(params['verify'] && !this.isMember) { if (this.user) { @@ -133,7 +129,7 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn if (this.user.email === this.verification.email.toLowerCase() && this.id === this.verification.entity && this.type === this.verification.type) { if (this.verification.verificationType === 'manager') { this.openManagerModal(); - } else if (this.verification.verificationType === 'member' && this.service === "monitor") { + } else if (this.verification.verificationType === 'member') { this.openMemberModal(); } else { this.openErrorModal(); @@ -217,6 +213,9 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn this.managerModal.cancel(); this.error = null; this.userManagementService.updateUserInfo(() => { + if (this.paramsSubscription instanceof Subscription) { + this.paramsSubscription.unsubscribe(); + } if (this.service === "monitor") { this.loading = false; this.router.navigate(['/admin/' + this.verification.entity]); @@ -254,8 +253,12 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn this.clearCacheService.clearCache('Members updated'); this.loading = false; this.error = null; + this.isMember = true; this.userManagementService.updateUserInfo(() => { - this.router.navigate([], {queryParams: {'verify': null, 'isMember': true}}); + if (this.paramsSubscription instanceof Subscription) { + this.paramsSubscription.unsubscribe(); + } + this.cancel(); }); }, error => { this.loading = false; @@ -271,6 +274,7 @@ export class RoleVerificationComponent implements OnInit, OnDestroy, AfterViewIn } cancel() { - this.router.navigate([], {queryParams: {'verify': null, 'isMember': null}}); + this.isMember = false; + this.router.navigate([]); } } diff --git a/searchPages/searchResearchResults.component.ts b/searchPages/searchResearchResults.component.ts index 5e4e3c59..f4f03fa7 100644 --- a/searchPages/searchResearchResults.component.ts +++ b/searchPages/searchResearchResults.component.ts @@ -160,7 +160,9 @@ export class SearchResearchResultsComponent { this.searchUtils.validateSize(params['size']); this.searchUtils.sortBy = (params['sortBy']) ? params['sortBy'] : ''; - if (this.searchUtils.sortBy && this.searchUtils.sortBy != "resultdateofacceptance,descending" && this.searchUtils.sortBy != "resultdateofacceptance,ascending") { + if (this.searchUtils.sortBy && this.searchUtils.sortBy != "resultdateofacceptance,descending" && this.searchUtils.sortBy != "resultdateofacceptance,ascending" + && this.searchUtils.sortBy != "citation_count,descending" && this.searchUtils.sortBy != "popularity,descending" + && this.searchUtils.sortBy != "influence,descending" && this.searchUtils.sortBy != "impulse,descending") { this.searchUtils.sortBy = ""; } this.selectedFields = []; diff --git a/searchPages/searchUtils/portal-search-result.component.html b/searchPages/searchUtils/portal-search-result.component.html index 9c202293..7be77b69 100644 --- a/searchPages/searchUtils/portal-search-result.component.html +++ b/searchPages/searchUtils/portal-search-result.component.html @@ -8,11 +8,11 @@ Member
-
+
restricted
- + private diff --git a/searchPages/searchUtils/searchSorting.component.ts b/searchPages/searchUtils/searchSorting.component.ts index f70ac1cf..e75e3930 100644 --- a/searchPages/searchUtils/searchSorting.component.ts +++ b/searchPages/searchUtils/searchSorting.component.ts @@ -1,5 +1,6 @@ import {Component, Input, Output, EventEmitter} from '@angular/core'; import {Option} from "../../sharedComponents/input/input.component"; +import {properties} from "../../../../environments/environment"; @Component({ selector: 'search-sorting', @@ -19,11 +20,21 @@ export class SearchSortingComponent { @Input() entityType: string = ''; @Output() sortByChange = new EventEmitter(); public options: Option[]; - private generalOptions = [ - {value: '', label: 'Relevance'}, - {value: 'resultdateofacceptance,descending', label: 'Date (most recent)'}, - {value: 'resultdateofacceptance,ascending', label: 'Date (least recent)'}, - ]; + private generalOptions = properties.environment != "production" ? + [ + {value: '', label: 'Relevance'}, + {value: 'resultdateofacceptance,descending', label: 'Date (most recent)'}, + {value: 'resultdateofacceptance,ascending', label: 'Date (least recent)'}, + {value: 'citation_count,descending', label: 'Citation Count'}, + {value: 'popularity,descending', label: 'Popularity'}, + {value: 'influence,descending', label: 'Influence'}, + {value: 'impulse,descending', label: 'Impulse'} + ] : + [ + {value: '', label: 'Relevance'}, + {value: 'resultdateofacceptance,descending', label: 'Date (most recent)'}, + {value: 'resultdateofacceptance,ascending', label: 'Date (least recent)'} + ]; private communityOptions = [ {value: '', label: 'Title'}, {value: 'creationdate,descending', label: 'Creation Date (most recent)'}, diff --git a/services/searchProjects.service.ts b/services/searchProjects.service.ts index 2109666f..b513b737 100644 --- a/services/searchProjects.service.ts +++ b/services/searchProjects.service.ts @@ -248,10 +248,10 @@ export class SearchProjectsService { } } } - if(resData.hasOwnProperty("startdate")) { + if(resData.hasOwnProperty("startdate") && resData['startdate']) { result.startYear = resData.startdate.split('-')[0]; } - if(resData.hasOwnProperty("enddate")) { + if(resData.hasOwnProperty("enddate") && resData['enddate']) { result.endYear = resData.enddate.split('-')[0]; } // Measure diff --git a/utils/authors/showAuthors.component.ts b/utils/authors/showAuthors.component.ts index a9987197..42296345 100644 --- a/utils/authors/showAuthors.component.ts +++ b/utils/authors/showAuthors.component.ts @@ -109,7 +109,7 @@ import {properties} from "../../../../environments/environment"; +{{authors.length - authorsLimit | number}} more - + +{{authors.length - authorsLimit | number}} Authors diff --git a/utils/dataTransfer/transferData.component.ts b/utils/dataTransfer/transferData.component.ts index 0c250dfe..4ca426d9 100644 --- a/utils/dataTransfer/transferData.component.ts +++ b/utils/dataTransfer/transferData.component.ts @@ -152,6 +152,7 @@ export class EGIDataTransferComponent { this.init(); if(!this.isMobile) { + this.egiTransferModal.stayOpen = true; // this.egiTransferModal.back = true; this.egiTransferModal.cancelButton = false; this.egiTransferModal.okButton = true; diff --git a/utils/email/composer.ts b/utils/email/composer.ts index 6fead2f0..d2df6d38 100644 --- a/utils/email/composer.ts +++ b/utils/email/composer.ts @@ -302,21 +302,23 @@ export class Composer { return message; } - public static composeEmailForCommunityDashboard(name: string, recipient: string) { + public static composeEmailForCommunityDashboard(name: string, role: "manager" | "member", recipient: string) { let email: Email = new Email(); email.subject = 'OpenAIRE Connect | ' + name; - email.body = this.composeMessageForCommunityDashboard(name); + email.body = this.composeMessageForCommunityDashboard(name, role); email.recipient = recipient; return email; } - public static composeMessageForCommunityDashboard(name: string, user: string = null, invitation: any = null) { + public static composeMessageForCommunityDashboard(name: string, role: "manager" | "member", user: string = null, invitation: any = null) { let message = '

Dear ((__user__)),

' + - '

You have been invited to be a manager of the OpenAIRE Research Community Dashboard for the ' + name + '.

' + + '

You have been invited to be a ' + role + ' of the OpenAIRE Research Community Dashboard for the ' + name + '.

' + '

Click this URL and use the verification code below to accept the invitation.

' + '

The verification code is ((__code__)).

' + + (role === 'manager'? '

As a manager of the OpenAIRE Research Community Dashboard, you will have access to the administration part of the dashboard, ' + - 'where you will be able to customize and manage the content of the ' + name + '.

' + + 'where you will be able to customize and manage the content of the ' + name + '.

': + '

As a member of the OpenAIRE Research Community Dashboard, you will have access to the community dashboard and link research results with projects, communities and other research projects.

') + '

Please contact us at ' + properties.helpdeskEmail + ' if you have any questions or concerns.

' + '

Kind Regards
The OpenAIRE Team

' + diff --git a/utils/entities/resultLandingInfo.ts b/utils/entities/resultLandingInfo.ts index 0ae3866f..30e1e76b 100644 --- a/utils/entities/resultLandingInfo.ts +++ b/utils/entities/resultLandingInfo.ts @@ -8,7 +8,7 @@ import { } from "../result-preview/result-preview"; export interface Id { - type: "pmid" | "doi" | "pmc" | "handle" | "openaire"; + type: "pmid" | "doi" | "pmc" | "handle" | "openaire" | "swhid"; value: string; trust: number } diff --git a/utils/entity-actions/entity-actions.component.ts b/utils/entity-actions/entity-actions.component.ts index 53cc9cc7..96d7ea49 100644 --- a/utils/entity-actions/entity-actions.component.ts +++ b/utils/entity-actions/entity-actions.component.ts @@ -16,7 +16,7 @@ import {EnvProperties} from "../properties/env-properties"; routerLinkActive="router-link-active" routerLink="/participate/direct-claim" [title]="'Link '+openaireEntities.RESULTS+' with a '+openaireEntities.PROJECT+', a '+openaireEntities.COMMUNITY+' or other '+openaireEntities.RESULTS+' and make the new information available in OpenAIRE information space.'" [attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small uk-width-medium'" - class="uk-flex uk-flex-middle uk-button-link uk-text-bolder" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-flex-center'"> + class="uk-flex uk-flex-middle uk-button-link" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-text-bolder uk-flex-center'"> Link to @@ -25,15 +25,15 @@ import {EnvProperties} from "../properties/env-properties"; - + class="uk-flex uk-flex-middle uk-button-link" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-text-bolder uk-flex-center'"> + Share
@@ -41,7 +41,7 @@ import {EnvProperties} from "../properties/env-properties"; + class="uk-flex uk-flex-middle uk-button-link" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-text-bolder uk-flex-center'"> Deposit @@ -50,7 +50,7 @@ import {EnvProperties} from "../properties/env-properties"; + class="uk-flex uk-flex-middle uk-button-link" [ngClass]="isMobile ? 'uk-margin-left uk-margin-xsmall-bottom' : 'uk-text-bolder uk-flex-center'"> Embed diff --git a/utils/properties/env-properties.ts b/utils/properties/env-properties.ts index af367504..4a2ccd68 100644 --- a/utils/properties/env-properties.ts +++ b/utils/properties/env-properties.ts @@ -44,6 +44,7 @@ export interface EnvProperties { cordisURL?: string; openDoarURL?: string; r3DataURL?: string; + swhURL?: string; fairSharingURL?: string, eoscMarketplaceURL?: string, sherpaURL?: string; diff --git a/utils/properties/environments/environment.all.ts b/utils/properties/environments/environment.all.ts new file mode 100644 index 00000000..020b7e89 --- /dev/null +++ b/utils/properties/environments/environment.all.ts @@ -0,0 +1,25 @@ +import {EnvProperties} from "../env-properties"; + +export let common: EnvProperties = { + swhURL: "https://archive.softwareheritage.org/", + // searchCrossrefAPIURL: "https://api.crossref.org/works", + // searchDataciteAPIURL: "https://api.datacite.org/works", + // searchOrcidURL: "https://pub.orcid.org/v2.1/", + // orcidURL: "https://orcid.org/", + // doiURL: "https://doi.org/", + // pmcURL: "http://europepmc.org/articles/", + // pmidURL: "https://www.ncbi.nlm.nih.gov/pubmed/", + // handleURL: "http://hdl.handle.net/", + // cordisURL: "http://cordis.europa.eu/projects/", + // openDoarURL: "http://v2.sherpa.ac.uk/id/repository/", + // r3DataURL: "http://service.re3data.org/repository/", + // fairSharingURL: "https://fairsharing.org/", + // sherpaURL: "http://sherpa.ac.uk/romeo/issn/", + // sherpaURLSuffix: "/", + // zenodo: "https://zenodo.org/", + // 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", +} \ No newline at end of file diff --git a/utils/properties/environments/environment.beta.ts b/utils/properties/environments/environment.beta.ts new file mode 100644 index 00000000..520b88e2 --- /dev/null +++ b/utils/properties/environments/environment.beta.ts @@ -0,0 +1,6 @@ +import {EnvProperties} from "../env-properties"; + +export let commonBeta: EnvProperties = { + // searchAPIURLLAst: "http://beta.services.openaire.eu/search/v2/api/", + // searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources", +} \ No newline at end of file diff --git a/utils/properties/environments/environment.prod.ts b/utils/properties/environments/environment.prod.ts new file mode 100644 index 00000000..a2aa22f8 --- /dev/null +++ b/utils/properties/environments/environment.prod.ts @@ -0,0 +1,6 @@ +import {EnvProperties} from "../env-properties"; + +export let commonProd: EnvProperties = { + // searchAPIURLLAst: "https://services.openaire.eu/search/v2/api/", + // searchResourcesAPIURL: "https://services.openaire.eu/search/v2/api/resources", +} \ No newline at end of file diff --git a/utils/properties/environments/environment.test.ts b/utils/properties/environments/environment.test.ts new file mode 100644 index 00000000..81abb978 --- /dev/null +++ b/utils/properties/environments/environment.test.ts @@ -0,0 +1,6 @@ +import {EnvProperties} from "../env-properties"; + +export let commonTest: EnvProperties = { + // searchAPIURLLAst: "https://services.openaire.eu/shadowSearch/v2/api/", + // searchResourcesAPIURL: "https://services.openaire.eu/shadowSearch/v2/api/resources", +} \ No newline at end of file diff --git a/utils/properties/environments/environment.ts b/utils/properties/environments/environment.ts new file mode 100644 index 00000000..69e7ceb1 --- /dev/null +++ b/utils/properties/environments/environment.ts @@ -0,0 +1,6 @@ +import {EnvProperties} from "../env-properties"; + +export let commonDev: EnvProperties = { + // searchAPIURLLAst: "http://beta.services.openaire.eu/search/v2/api/", + // searchResourcesAPIURL: "https://beta.services.openaire.eu/search/v2/api/resources", +} \ No newline at end of file diff --git a/utils/properties/searchFields.ts b/utils/properties/searchFields.ts index 7ae0fcda..65ca6a4b 100644 --- a/utils/properties/searchFields.ts +++ b/utils/properties/searchFields.ts @@ -14,7 +14,7 @@ export class SearchFields { // Remove Collected From Filter "collectedfrom","collectedfrom" public RESULT_REFINE_FIELDS = [ - "resultbestaccessright", "instancetypename", "foslabel", "relfunder", + "resultbestaccessright", "instancetypename", properties.environment!='production'?"foslabel":'fos', "relfunder", "relfundinglevel0_id", "relfundinglevel1_id", "relfundinglevel2_id", "relproject", "sdg", "country", "resultlanguagename", "resulthostingdatasource", "community"]; diff --git a/utils/result-preview/result-preview.component.html b/utils/result-preview/result-preview.component.html index d8608abb..c4574c8d 100644 --- a/utils/result-preview/result-preview.component.html +++ b/utils/result-preview/result-preview.component.html @@ -214,7 +214,8 @@ - {{result.measure.bip[0].value}} + {{formatNumber(result.measure.bip[0].value)}} + {{result.measure.bip[0].value}}
@@ -223,7 +224,8 @@ - + +
{{metric.name}}{{metric.value}}{{metric.value | number}}{{metric.value}}
@@ -252,7 +254,7 @@
Powered by BIP! + loading="lazy" alt="Usage counts">
diff --git a/utils/result-preview/result-preview.component.ts b/utils/result-preview/result-preview.component.ts index 9c041854..6352e9b9 100644 --- a/utils/result-preview/result-preview.component.ts +++ b/utils/result-preview/result-preview.component.ts @@ -223,6 +223,10 @@ export class ResultPreviewComponent implements OnInit, OnChanges { return formatted.number + formatted.size; } + public isNumber(value): boolean { + return typeof value === 'number'; + } + public getAccessLabel(accessRight) : string { if(accessRight) { return (accessRight + (accessRight.toLowerCase().endsWith(" access") ? "" : " access")); diff --git a/utils/result-preview/result-preview.ts b/utils/result-preview/result-preview.ts index b7a2450b..11ee68c5 100644 --- a/utils/result-preview/result-preview.ts +++ b/utils/result-preview/result-preview.ts @@ -11,6 +11,7 @@ export interface HostedByCollectedFrom { years: string[]; accessRightIcon: string; license?: string; + fulltext?: string; } export interface Journal { diff --git a/utils/string-utils.class.ts b/utils/string-utils.class.ts index d05bc57e..dff363ff 100644 --- a/utils/string-utils.class.ts +++ b/utils/string-utils.class.ts @@ -149,7 +149,7 @@ export class DOI { } export class Identifier { - class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" | "re3data" = null; + class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" | "re3data" | "swhid" = null; id: string; public static getDOIsFromString(str: string): string[] { @@ -202,13 +202,15 @@ export class Identifier { return {"class": "handle", "id": pid}; } else if (Identifier.isValidRe3Data(pid)) { return {"class": "re3data", "id": pid}; + } else if (Identifier.isValidSwhId(pid)) { + return {"class": "swhid", "id": pid}; } //set it as a doi, to catch the case that doi has not valid format return (strict?null:{"class": "doi", "id": pid}); } public static getPIDFromIdentifiers(identifiers: Map): Identifier { - let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data"]; + let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data", "swhid"]; if(identifiers) { for (let cl of classes) { if (identifiers.get(cl)) { @@ -257,6 +259,12 @@ export class Identifier { let exp = /(r3d[1-9]\d{0,8})/g; return str.match(exp) != null; } + + public static isValidSwhId(str: string): boolean { + // let exp = /swh:1:(snp|rel|rev|dir|cnt):[0-9a-f]{40}/g; + let exp = /swh:1:snp:[0-9a-f]{40}/g; + return str.match(exp) != null; + } } export class StringUtils {