diff --git a/claims/claim-utils/claimHelper.class.ts b/claims/claim-utils/claimHelper.class.ts index 9b914ab5..d3fb38f4 100644 --- a/claims/claim-utils/claimHelper.class.ts +++ b/claims/claim-utils/claimHelper.class.ts @@ -28,6 +28,7 @@ export class ClaimResult { export class ClaimProject { public funderId: string; + public funderShortname: string; public funderName: string; public acronym: string; public startDate: string; @@ -92,6 +93,7 @@ export class ClaimRecord2Insert { targetAccessRights: string; targetEmbargoEndDate: string; claimedInDashboard: string; + idSuffix:string; constructor() { diff --git a/claims/claim-utils/claimProjectSearchForm.component.ts b/claims/claim-utils/claimProjectSearchForm.component.ts index 01e6d8c0..70b154e6 100644 --- a/claims/claim-utils/claimProjectSearchForm.component.ts +++ b/claims/claim-utils/claimProjectSearchForm.component.ts @@ -65,35 +65,36 @@ export class ClaimProjectsSearchFormComponent { } search(page,size) { - if(this.keyword.length == 0){ - this.showResults =false; + if (this.keyword.length == 0) { + this.showResults = false; return; } - this.showResults =true; + this.showResults = true; this.openaireResults = []; this.openaireResultsStatus = this.errorCodes.LOADING; this.prevFilters = this.filters; //searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] , properties:EnvProperties ):any { - this.sub = this._projectService.searchProjects(this.createOpenaireQueryParams(),(page==1)? this.refineFieldsQuery:null, page, size, (page==1)?this.refineFields:[], this.properties).subscribe( + this.sub = this._projectService.advancedSearchProjects(this.createOpenaireQueryParams(), page, size, this.properties, (page == 1) ? this.refineFieldsQuery : null, (page == 1) ? this.refineFields : [], this.createOpenaireRefineQuery()).subscribe( + // this.sub = this._projectService.searchProjects(this.createOpenaireQueryParams(),(page==1)? this.refineFieldsQuery:null, page, size, (page==1)?this.refineFields:[], this.properties).subscribe( data => { - if(data != null) { - this.openaireResultsPage=page; - this.openaireResultsNum = data[0]; - this.openaireResults =ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties); - if(data[2] && data[2].length > 0){ - this.filters = this.checkSelectedFilters( data[2], this.prevFilters); - } - - this.openaireResultsStatus = this.errorCodes.DONE; - if(this.openaireResultsNum == 0){ - this.openaireResultsStatus = this.errorCodes.NONE; - this.filters = this.checkSelectedFilters( [], this.prevFilters); - } - }else { - this.openaireResultsStatus = this.errorCodes.ERROR; + if (data != null) { + this.openaireResultsPage = page; + this.openaireResultsNum = data[0]; + this.openaireResults = ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties); + if (data[2] && data[2].length > 0) { + this.filters = this.checkSelectedFilters(data[2], this.prevFilters); } - }, + + this.openaireResultsStatus = this.errorCodes.DONE; + if (this.openaireResultsNum == 0) { + this.openaireResultsStatus = this.errorCodes.NONE; + this.filters = this.checkSelectedFilters([], this.prevFilters); + } + } else { + this.openaireResultsStatus = this.errorCodes.ERROR; + } + }, err => { this.openaireResultsStatus = this.errorCodes.ERROR; //console.log(err.status); @@ -177,9 +178,10 @@ export class ClaimProjectsSearchFormComponent { const entity: ClaimEntity = new ClaimEntity(); entity.project = new ClaimProject(); entity.project.funderId = item.funderId; - entity.project.funderName = item.funderShortname; + entity.project.funderShortname = item.funderShortname?item.funderShortname:(entity.project.funderId.split("::")[1]); + entity.project.funderName = item.funderName; entity.id = item.id; - entity.project.url = properties.searchLinkToProject + entity.id; + entity.project.url = (item.code !="unidentified") ? properties.searchLinkToProject + entity.id : null; entity.title = item.title.name; entity.project.acronym = item.acronym; entity.project.startDate = item.startYear; @@ -202,12 +204,16 @@ export class ClaimProjectsSearchFormComponent { } - createOpenaireQueryParams():string { + createOpenaireQueryParams(): string { let query = ""; - if(this.keyword.length > 0){ - query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword)); + if (this.keyword.length > 0) { + // query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword)); + query += StringUtils.quote(StringUtils.URIEncode(this.keyword)); } + return query; + } + createOpenaireRefineQuery(): string { /*if(this.startYear.length > 0 ){ query+='&fq=projectstartyear exact \"'+this.startYear+'\"' } @@ -215,30 +221,30 @@ export class ClaimProjectsSearchFormComponent { query+='&fq=projectendyear exact \"'+this.endYear+'\"' }*/ let allFqs = ""; - for (let filter of this.filters){ - if(filter.countSelectedValues > 0){ - let count_selected=0; + for (let filter of this.filters) { + if (filter.countSelectedValues > 0) { + let count_selected = 0; let fq = ""; - for (let value of filter.values){ - if(value.selected == true){ + for (let value of filter.values) { + if (value.selected == true) { count_selected++; - fq+=(fq.length > 0 ? " " + filter.filterOperator + " ":"" ) + filter.filterId + " exact " + (StringUtils.quote(value.id)); + fq += (fq.length > 0 ? " " + filter.filterOperator + " " : "") + filter.filterId + " exact " + (StringUtils.quote(value.id)); } } - if(count_selected > 0){ - fq="&fq="+StringUtils.URIEncode(fq); + if (count_selected > 0) { + fq = "&fq=" + StringUtils.URIEncode(fq); allFqs += fq; } } } - for (let i=0; i=" ,"<=", "and" ) + allFqs += NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i], filter.selectedFromValue, filter.selectedToValue, " within ", ">=", "<=", "and") } - return query+allFqs; - + return allFqs + "&type=projects"; } + public yearChanged() { this.search(this.page, this.size); @@ -273,20 +279,21 @@ export class ClaimProjectsSearchFormComponent { } } - + filter.countAllValues = filter.values.length; } if(filters.length == 0 ){ - for(let j=0; j< prevFilters.length ; j++){ - let filter = Object.assign({}, prevFilters[j]); - filter.values = []; - for(let filterValue of prevFilters[j].values) { - if(filterValue.selected){ - filterValue.number = 0; - filter.values.push(filterValue); - } - } - filters.push(filter) + for(let j=0; j< prevFilters.length ; j++) { + let filter = Object.assign({}, prevFilters[j]); + filter.values = []; + for (let filterValue of prevFilters[j].values) { + if (filterValue.selected) { + filterValue.number = 0; + filter.values.push(filterValue); } + } + filter.countAllValues = filter.values.length; + filters.push(filter) + } } return filters; } diff --git a/claims/claim-utils/displayClaims/displayClaims.component.html b/claims/claim-utils/displayClaims/displayClaims.component.html index bdcc74b3..94034a2e 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.html +++ b/claims/claim-utils/displayClaims/displayClaims.component.html @@ -56,57 +56,76 @@
No links found
- +
+ +
+ diff --git a/claims/claim-utils/displayClaims/displayClaims.component.less b/claims/claim-utils/displayClaims/displayClaims.component.less index 0eadec18..e322586c 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.less +++ b/claims/claim-utils/displayClaims/displayClaims.component.less @@ -4,14 +4,4 @@ position: relative; padding: 0 20px; height: 100%; - - &::before { - content: ''; - position: absolute; - top: 0; - left: 50%; - right: 0; - bottom: 0; - border-left: @global-border-width solid @global-border; - } } diff --git a/claims/claim-utils/displayClaims/displayClaims.component.ts b/claims/claim-utils/displayClaims/displayClaims.component.ts index 9e5ccf97..8fd1f4ee 100644 --- a/claims/claim-utils/displayClaims/displayClaims.component.ts +++ b/claims/claim-utils/displayClaims/displayClaims.component.ts @@ -52,6 +52,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { lastIndexDate = null; public filterForm: FormGroup; public entities: string[] = []; + selected = []; allOptions: Option[] = [ {label: OpenaireEntities.PUBLICATIONS, value: "publication"}, @@ -310,23 +311,34 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { } isSelected(value: string) { - return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value) + return this.filterForm && this.filterForm.get('entities').value.find(entity => entity === value); } - deleteOpen(index: number) { + deleteOpen(index: number = null) { this.index = index; this.deleteModal.alertTitle = 'Delete Confirmation'; - this.deleteModal.message = 'Are you sure you want to delete this link?'; + this.deleteModal.message = 'Are you sure you want to delete ' + (this.index != null ? '1' : this.selected.length) + ' link(s)?'; this.deleteModal.okButtonText = 'Yes'; this.deleteModal.open(); } delete() { - this.subscriptions.push(this._claimService.deleteBulk([this.claims[this.index].id], this.properties.claimsAPIURL).subscribe( + let claimsToBeDeleted = ((this.index != null) ? [this.claims[this.index].id] : this.selected.map(claim => claim.id)); + console.log(claimsToBeDeleted); + this.subscriptions.push(this._claimService.deleteBulk(claimsToBeDeleted, this.properties.claimsAPIURL).subscribe( res => { - this.claims.splice(this.index, 1); - this.resultsNum = this.resultsNum - 1; - NotificationHandler.rise('Link has been deleted successfully'); + if (this.index != null) { + this.claims.splice(this.index, 1); + this.resultsNum = this.resultsNum - 1; + NotificationHandler.rise('Link has been deleted successfully'); + } else { + claimsToBeDeleted.forEach(claimId => { + this.claims.splice(this.claims.findIndex((id) => id == claimId), 1); + }); + this.resultsNum = this.resultsNum - claimsToBeDeleted.length; + NotificationHandler.rise(claimsToBeDeleted.length + ' links have been deleted successfully'); + } + this.selected = []; let goToPage = this.page; if (this.totalPages(this.resultsNum) < this.page && this.page > 0) { goToPage = this.page - 1; @@ -334,7 +346,8 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { this.goTo(goToPage); }, err => { this.handleErrors(err, "Error deleting claim with id: " + this.claims[this.index].id); - })); + } + )); } pageChange($event) { @@ -351,7 +364,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { if (claimDateStr < lastUpdateDateStr) { return true; } else { - return claim.target.collectedFrom != "infrastruct_::openaire" && claim.indexed; + return claim.target.collectedFrom != "infrastruct_::openaire"; } } @@ -362,7 +375,44 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy { } return totalPages; } - + + selectClaim(item: any, event) { + let value = event.currentTarget.checked; + if (value) { + this.selected.push(item); + } else { + for (var _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if (claim['id'] == item.id) { + this.selected.splice(_i, 1); + } + } + } + } + + selectAll(event) { + let value = event.currentTarget.checked; + if (value) { + this.selected = []; + for (let _i = 0; _i < this.claims.length; _i++) { + let claim = this.claims[_i]; + this.selected.push(claim); + } + } else { + this.selected = []; + } + } + + isSelectedClaim(id: string) { + for (let _i = 0; _i < this.selected.length; _i++) { + let claim = this.selected[_i]; + if (claim['id'] == id) { + return true; + } + } + return false; + } + private updateDescription(description: string) { this._meta.updateTag({content: description}, "name='description'"); this._meta.updateTag({content: description}, "property='og:description'"); diff --git a/claims/claim-utils/displayClaims/displayClaims.module.ts b/claims/claim-utils/displayClaims/displayClaims.module.ts index 6ecda833..99134994 100644 --- a/claims/claim-utils/displayClaims/displayClaims.module.ts +++ b/claims/claim-utils/displayClaims/displayClaims.module.ts @@ -17,7 +17,6 @@ import {HelperModule} from '../../../utils/helper/helper.module'; import {Schema2jsonldModule} from '../../../sharedComponents/schema2jsonld/schema2jsonld.module'; import { SEOServiceModule } from '../../../sharedComponents/SEO/SEOService.module'; import {IndexInfoServiceModule} from "../../../utils/indexInfoService.module"; -import {PiwikServiceModule} from "../../../utils/piwik/piwikService.module"; import {SearchInputModule} from '../../../sharedComponents/search-input/search-input.module'; import {InputModule} from '../../../sharedComponents/input/input.module'; import {LoadingModule} from '../../../utils/loading/loading.module'; @@ -30,7 +29,7 @@ import {link} from "../../../utils/icons/icons"; @NgModule({ imports: [ CommonModule, FormsModule, RouterModule, ClaimServiceModule, LoadingModalModule, AlertModalModule, - ClaimEntityFormatterModule, PagingModule, HelperModule, Schema2jsonldModule, SEOServiceModule, PiwikServiceModule, + ClaimEntityFormatterModule, PagingModule, HelperModule, Schema2jsonldModule, SEOServiceModule, IndexInfoServiceModule, MatSelectModule, SearchInputModule, MatAutocompleteModule, MatChipsModule, MatFormFieldModule, MatSlideToggleModule, InputModule, LoadingModule, NoLoadPaging, IconsModule, DropdownFilterModule ], diff --git a/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts index 6102d684..547e4c16 100644 --- a/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts +++ b/claims/claim-utils/entityFormatter/claimEntityFormatter.component.ts @@ -15,21 +15,22 @@ import {StringUtils} from "../../../utils/string-utils.class";
{{getEntityName(type)}}
-
- Link to: +
+ Link to:
-
- Link to: +
+ Link to:
-
- Link to: - {{entity.title}} +
+ Link to: +
+ {{entity.title}} +
` }) diff --git a/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts index 92557d9a..14ee0e60 100644 --- a/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts +++ b/claims/claim-utils/entityFormatter/projectTitleFormatter.component.ts @@ -20,7 +20,7 @@ import {properties} from "../../../../../environments/environment"; - Funder: {{project['funderName']}} + Funder: {{project['funderName']}} ` }) diff --git a/claims/claim-utils/service/searchDatacite.service.ts b/claims/claim-utils/service/searchDatacite.service.ts index 4361462f..a6d9cc8b 100644 --- a/claims/claim-utils/service/searchDatacite.service.ts +++ b/claims/claim-utils/service/searchDatacite.service.ts @@ -58,22 +58,20 @@ export class SearchDataciteService { entity.result.journal = null; entity.result.DOI = item.attributes.doi; entity.id = item.attributes.doi; - entity.title = item.attributes.title; + entity.title = Array.isArray(item.attributes.titles) && item.attributes.titles[0].title?item.attributes.titles[0].title:null; entity.result.url = properties.doiURL + item.attributes.doi; entity.result.source = 'datacite'; entity.type = 'dataset'; - entity.result.date = item.attributes.published; + entity.result.date = item.attributes.publicationYear; entity.result.accessRights = "OPEN"; - entity.result.publisher = item.attributes['container-title']; + entity.result.publisher = item.attributes['publisher']; entity.result.journal = null; entity.result.record = item; - if (item.attributes.author) { + if (item.attributes.creators) { entity.result.authors = []; - for (let j = 0; j < item.attributes.author.length; j++) { - const author = item.attributes.author[j]; - if(author.family || author.literal) { - entity.result.authors.push((author.family) ? author.family + (author.given ? ', ' + author.given : '') : author.literal); - } + for (let j = 0; j < item.attributes.creators.length; j++) { + const author = item.attributes.creators[j].name; + entity.result.authors.push(author); } } results.push(entity); diff --git a/claims/claimsAdmin/claimsAdmin.module.ts b/claims/claimsAdmin/claimsAdmin.module.ts index ace19292..89caa0d6 100644 --- a/claims/claimsAdmin/claimsAdmin.module.ts +++ b/claims/claimsAdmin/claimsAdmin.module.ts @@ -3,9 +3,6 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../../openaireLibrary/shared/shared.module'; import { ClaimsAdminComponent } from './claimsAdmin.component'; import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; -import { AdminLoginGuard} from'../../login/adminLoginGuard.guard'; -import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; -import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; @NgModule({ imports: [ @@ -13,7 +10,7 @@ import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; DisplayClaimsModule ], - providers:[AdminLoginGuard, PreviousRouteRecorder,IsRouteEnabled], + providers:[], declarations: [ ClaimsAdminComponent ], diff --git a/claims/directLinking/directLinking.component.ts b/claims/directLinking/directLinking.component.ts index 3fcd7537..70d46032 100644 --- a/claims/directLinking/directLinking.component.ts +++ b/claims/directLinking/directLinking.component.ts @@ -156,6 +156,7 @@ export class DirectLinkingComponent { entity.project.code = project.code; entity.project.endDate = project.endDate; entity.project.funderId = project.funderId; + entity.project.funderShortname = project.funderShortName?project.funderShortName:(entity.project.funderId.split("::")[1]); entity.project.funderName = project.funderName; entity.project.fundingLevel0 = project.fundingLevel0; entity.project.jurisdiction = project.jurisdiction; diff --git a/claims/directLinking/directLinking.module.ts b/claims/directLinking/directLinking.module.ts index a9bea79c..9505f79d 100644 --- a/claims/directLinking/directLinking.module.ts +++ b/claims/directLinking/directLinking.module.ts @@ -5,9 +5,6 @@ import { DirectLinkingComponent } from './directLinking.component'; import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; import {SearchResearchResultsServiceModule} from '../../services/searchResearchResultsService.module'; -import {LoginGuard} from'../../login/loginGuard.guard'; -import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; -import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module'; import {LinkingGenericModule} from '../linking/linkingGeneric.module'; @@ -18,7 +15,7 @@ import {LinkingGenericModule} from '../linking/linkingGeneric.module'; EntitySearchServiceModule, SearchResearchResultsServiceModule, Schema2jsonldModule, SEOServiceModule, LinkingGenericModule ], - providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + providers:[], declarations: [ DirectLinkingComponent ], exports:[DirectLinkingComponent] diff --git a/claims/linking/bulkClaim/bulkClaim.component.ts b/claims/linking/bulkClaim/bulkClaim.component.ts index fac882b3..79654726 100644 --- a/claims/linking/bulkClaim/bulkClaim.component.ts +++ b/claims/linking/bulkClaim/bulkClaim.component.ts @@ -269,11 +269,16 @@ export class BulkClaimComponent { } }, err => { - //console.log(err); + // console.log(err); BulkClaimComponent.handleError("Error getting crossref by DOIs: " + id, err); - this.notFoundIds.push(id); - this.notFoundIdsRow.push(row); - this.endOfFetching(); + + if(err.status == 404) { + this.searchInDatacite(id, accessMode, date, row); + } else { + this.notFoundIds.push(id); + this.notFoundIdsRow.push(row); + this.endOfFetching(); + } } )); } diff --git a/claims/linking/insertClaim/insertClaim.component.ts b/claims/linking/insertClaim/insertClaim.component.ts index d9314aeb..0cf983e5 100644 --- a/claims/linking/insertClaim/insertClaim.component.ts +++ b/claims/linking/insertClaim/insertClaim.component.ts @@ -156,13 +156,14 @@ export class ClaimInsertComponent { this.loading.open(); let claims: ClaimRecord2Insert[] = []; let directclaims: DirectIndexRecord[] = []; + let idSuffix = (new Date()).getTime() + ""; let dashboard = this.properties.environment+"_"+this.properties.dashboard + (this.communityId?("_"+this.communityId):''); for (let j = 0; j < this.sources.length; j++) { // if an external result -> direct insert in the index const result: ClaimEntity = this.sources[j]; if (result.result && ["crossref", "datacite", "orcid"].indexOf(result.result.source) != -1) { directclaims.push({ "id": result.id, - "record": ClaimInsertComponent.createDirectClaim(result, this.results) + "record": ClaimInsertComponent.createDirectClaim(result, this.results, idSuffix) }); } } @@ -173,12 +174,12 @@ export class ClaimInsertComponent { if (this.sources.length > 0) { directclaims.push({ "id": entity.id, - "record": ClaimInsertComponent.createDirectClaim(entity, this.sources) + "record": ClaimInsertComponent.createDirectClaim(entity, this.sources, idSuffix) }); } else if (this.inlineEntity) { directclaims.push({ "id": entity.id, - "record": ClaimInsertComponent.createDirectClaim(entity, [this.inlineEntity]) + "record": ClaimInsertComponent.createDirectClaim(entity, [this.inlineEntity], idSuffix) }); } @@ -187,11 +188,11 @@ export class ClaimInsertComponent { for (let j = 0; j < this.sources.length; j++) { const result: ClaimEntity = this.sources[j]; // this is a research result if (entity.result) { - claims.push(ClaimInsertComponent.createResultClaim(result, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createResultClaim(result, entity, user.email, dashboard, idSuffix)); } else if (entity.context) { - claims.push(ClaimInsertComponent.createContextClaim(result, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createContextClaim(result, entity, user.email, dashboard, idSuffix)); } else if (entity.project) { - claims.push(ClaimInsertComponent.createProjectClaim(result, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createProjectClaim(result, entity, user.email, dashboard, idSuffix)); } this.infoToLog.push([ result.title?result.title: result.id, entity.title?entity.title:entity.id]); @@ -201,15 +202,15 @@ export class ClaimInsertComponent { if (this.inlineEntity.result) { if (entity.result) { - claims.push(ClaimInsertComponent.createResultClaim(this.inlineEntity, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createResultClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix)); } else if (entity.context) { - claims.push(ClaimInsertComponent.createContextClaim(this.inlineEntity, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createContextClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix)); } else if (entity.project) { - claims.push(ClaimInsertComponent.createProjectClaim(this.inlineEntity, entity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createProjectClaim(this.inlineEntity, entity, user.email, dashboard, idSuffix)); } } else if (this.inlineEntity.project) { if (entity.result) { - claims.push(ClaimInsertComponent.createProjectClaim(entity, this.inlineEntity, user.email, dashboard)); + claims.push(ClaimInsertComponent.createProjectClaim(entity, this.inlineEntity, user.email, dashboard, idSuffix)); } } } @@ -390,7 +391,7 @@ export class ClaimInsertComponent { } - private static createContextClaim(resultEntity: ClaimEntity, contextEntity: ClaimEntity, user: any, dashboard:string): ClaimRecord2Insert { + private static createContextClaim(resultEntity: ClaimEntity, contextEntity: ClaimEntity, user: any, dashboard:string, idSuffix:string): ClaimRecord2Insert { return { claimedBy: user, sourceId: contextEntity.context.concept.id, @@ -403,11 +404,12 @@ export class ClaimInsertComponent { targetCollectedFrom: resultEntity.result.source, targetAccessRights: resultEntity.result.accessRights, targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity), - claimedInDashboard : dashboard + claimedInDashboard : dashboard, + idSuffix : idSuffix }; } - private static createProjectClaim(resultEntity: ClaimEntity, projectEntity: ClaimEntity, user: any, dashboard:string): ClaimRecord2Insert { + private static createProjectClaim(resultEntity: ClaimEntity, projectEntity: ClaimEntity, user: any, dashboard:string, idSuffix:string): ClaimRecord2Insert { return { claimedBy: user, sourceId: projectEntity.id, @@ -420,11 +422,12 @@ export class ClaimInsertComponent { targetCollectedFrom: resultEntity.result.source, targetAccessRights: resultEntity.result.accessRights, targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity), - claimedInDashboard : dashboard + claimedInDashboard : dashboard, + idSuffix : idSuffix }; } - private static createResultClaim(inlineResult: ClaimEntity, resultEntity: ClaimEntity, user: string, dashboard:string): ClaimRecord2Insert { + private static createResultClaim(inlineResult: ClaimEntity, resultEntity: ClaimEntity, user: string, dashboard:string, idSuffix:string): ClaimRecord2Insert { return { claimedBy: user, @@ -438,7 +441,9 @@ export class ClaimInsertComponent { targetCollectedFrom: inlineResult.result.source, targetAccessRights: inlineResult.result.accessRights, targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(inlineResult), - claimedInDashboard : dashboard + claimedInDashboard : dashboard, + idSuffix : idSuffix + }; } @@ -448,12 +453,13 @@ export class ClaimInsertComponent { } return "" } - - static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[]) { + static createOpenAIREId(id, idSuffix:string):string { + return id.indexOf( "::" ) == -1 ? ("userclaim___::" + Md5.hashStr(id + idSuffix)):id; + } + static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[], idSuffix:string) { let entity = {}; - const md5_id = Md5.hashStr(resultEntity.id); - entity["originalId"] = "userclaim___::" + md5_id; - entity["openaireId"] = "userclaim___::" + md5_id; + entity["originalId"] = this.createOpenAIREId(resultEntity.id, idSuffix); + entity["openaireId"] = this.createOpenAIREId(resultEntity.id, idSuffix); entity["title"] = resultEntity.title; entity["title"] = (Array.isArray(resultEntity.title) && resultEntity.title.length > 0) ? resultEntity.title[0] : resultEntity.title; @@ -502,7 +508,7 @@ export class ClaimInsertComponent { entity["linksToProjects"] = []; } let project: ClaimEntity = results[i]; - entity["linksToProjects"].push("info:eu-repo/grantAgreement/" + project.project.funderName + "/" + project.project.fundingLevel0 + "/" + project.project.code + "/" + project.project.jurisdiction + "/" + project.title + "/" + project.project.acronym); + entity["linksToProjects"].push("info:eu-repo/grantAgreement/" + project.project.funderShortname + "/" + project.project.fundingLevel0 + "/" + project.project.code + "/" + project.project.jurisdiction + "/" + project.title + "/" + project.project.acronym); } else if (results[i].context) { diff --git a/claims/linking/linkingGeneric.module.ts b/claims/linking/linkingGeneric.module.ts index 5d49a3b5..0ec6eafe 100644 --- a/claims/linking/linkingGeneric.module.ts +++ b/claims/linking/linkingGeneric.module.ts @@ -7,20 +7,16 @@ import {SelectedContextsModule} from './selected/selectedContexts.module'; import {SelectedPublicationsModule} from './selected/selectedResults.module'; import {LinkingGenericComponent} from './linkingGeneric.component'; import {StartOverModule} from '../claim-utils/startOver.module'; -import {LoginGuard} from '../../login/loginGuard.guard'; -import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; import {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module'; import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; import {HelperModule} from '../../utils/helper/helper.module'; -import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module'; import {MetadataPreviewModule} from './selected/metadataPreview.module'; import {ClaimEntitiesMetadataModule} from "./selected/ClaimEntitiesMetadata.module"; import {AlertModalModule} from '../../utils/modal/alertModal.module'; -import {PiwikServiceModule} from "../../utils/piwik/piwikService.module"; import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module"; import {StepperModule} from "../../sharedComponents/stepper/stepper.module"; import {IconsModule} from "../../utils/icons/icons.module"; @@ -34,10 +30,9 @@ import {link} from "../../utils/icons/icons"; StartOverModule, ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule, HelperModule, Schema2jsonldModule, SEOServiceModule, MetadataPreviewModule, ClaimEntitiesMetadataModule, AlertModalModule, - PiwikServiceModule, MatSelectModule, BreadcrumbsModule, StepperModule, IconsModule ], - providers: [LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + providers: [], declarations: [ LinkingGenericComponent ], exports: [ diff --git a/claims/linking/selected/ClaimEntityProjectMetadata.component.ts b/claims/linking/selected/ClaimEntityProjectMetadata.component.ts index 0b90acc6..229ebeca 100644 --- a/claims/linking/selected/ClaimEntityProjectMetadata.component.ts +++ b/claims/linking/selected/ClaimEntityProjectMetadata.component.ts @@ -16,10 +16,10 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
-
- Funder: {{entity.project.funderName}} +
+ Funder: {{entity.project.funderName?entity.project.funderName:entity.project.funderShortname}}
-
+
Project Code: {{entity.project.code}}
diff --git a/claims/myClaims/myClaims.module.ts b/claims/myClaims/myClaims.module.ts index 20d97331..bb87055d 100644 --- a/claims/myClaims/myClaims.module.ts +++ b/claims/myClaims/myClaims.module.ts @@ -3,9 +3,6 @@ import { NgModule } from '@angular/core'; import { SharedModule } from '../../../openaireLibrary/shared/shared.module'; import { MyClaimsComponent } from './myClaims.component'; import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; -import {LoginGuard} from'../../login/loginGuard.guard'; -import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; -import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; @NgModule({ imports: [ @@ -13,7 +10,7 @@ import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; DisplayClaimsModule ], - providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], + providers:[], declarations: [ MyClaimsComponent ], exports: [MyClaimsComponent] diff --git a/dashboard/divId/divIds.module.ts b/dashboard/divId/divIds.module.ts index eca996e6..dbdcb477 100644 --- a/dashboard/divId/divIds.module.ts +++ b/dashboard/divId/divIds.module.ts @@ -15,9 +15,10 @@ import {LoadingModule} from "../../utils/loading/loading.module"; @NgModule({ imports: [ + ClassesRoutingModule, CommonModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, - AdminTabsModule, PageContentModule, ClassesRoutingModule, SearchInputModule, IconsModule, LoadingModule + AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule ], declarations: [DivIdsComponent], exports: [DivIdsComponent] diff --git a/dashboard/divhelpcontent/class-help-content-form.module.ts b/dashboard/divhelpcontent/class-help-content-form.module.ts index 5f0bec5c..9e0b061a 100644 --- a/dashboard/divhelpcontent/class-help-content-form.module.ts +++ b/dashboard/divhelpcontent/class-help-content-form.module.ts @@ -16,9 +16,10 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m @NgModule({ imports: [ + ClassHelpContentFormRoutingModule, CommonModule, FormsModule, RouterModule, SafeHtmlPipeModule, CKEditorModule, - AlertModalModule, ReactiveFormsModule, ClassHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule + AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule ], declarations: [ ClassContentFormComponent diff --git a/dashboard/divhelpcontent/class-help-contents.module.ts b/dashboard/divhelpcontent/class-help-contents.module.ts index 8e350d1d..ecd80574 100644 --- a/dashboard/divhelpcontent/class-help-contents.module.ts +++ b/dashboard/divhelpcontent/class-help-contents.module.ts @@ -19,8 +19,9 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m @NgModule({ imports: [ + ClassHelpContentsRoutingModule, CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule, - AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, ClassHelpContentsRoutingModule, + AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule, PageContentModule ], declarations: [ diff --git a/dashboard/entity/entities.module.ts b/dashboard/entity/entities.module.ts index 52843fb9..a112018c 100644 --- a/dashboard/entity/entities.module.ts +++ b/dashboard/entity/entities.module.ts @@ -17,8 +17,9 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module"; @NgModule({ imports: [ + EntitiesRoutingModule, CommonModule, RouterModule, FormsModule, AdminToolServiceModule, - AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, EntitiesRoutingModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule + AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule ], declarations: [EntitiesComponent], exports: [EntitiesComponent] diff --git a/dashboard/helpTexts/page-help-content-form.module.ts b/dashboard/helpTexts/page-help-content-form.module.ts index 27e34ae4..714ee256 100644 --- a/dashboard/helpTexts/page-help-content-form.module.ts +++ b/dashboard/helpTexts/page-help-content-form.module.ts @@ -16,9 +16,10 @@ import {MatSlideToggleModule} from "@angular/material/slide-toggle"; @NgModule({ imports: [ + PageHelpContentFormRoutingModule, CommonModule, FormsModule, RouterModule, SafeHtmlPipeModule, CKEditorModule, - AlertModalModule, ReactiveFormsModule, PageHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule + AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule ], declarations: [PageContentFormComponent], exports: [PageContentFormComponent] diff --git a/dashboard/helpTexts/page-help-contents.module.ts b/dashboard/helpTexts/page-help-contents.module.ts index 10bc383f..8a2876df 100644 --- a/dashboard/helpTexts/page-help-contents.module.ts +++ b/dashboard/helpTexts/page-help-contents.module.ts @@ -17,8 +17,9 @@ import {HTMLToStringPipeModule} from '../../utils/pipes/HTMLToStringPipe.module' @NgModule({ imports: [ + PageHelpContentsRoutingModule, CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule, - AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageHelpContentsRoutingModule, PageContentModule, + AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule ], declarations: [ diff --git a/dashboard/menu/menu.component.ts b/dashboard/menu/menu.component.ts index d756a77f..9f89224b 100644 --- a/dashboard/menu/menu.component.ts +++ b/dashboard/menu/menu.component.ts @@ -372,10 +372,8 @@ export class MenuComponent implements OnInit { } public valueChange() { - this.elements.disable(); this.cdr.detectChanges(); this.elements.init(); - this.elements.enable(); } public get displayMenuItems() { diff --git a/dashboard/menu/menu.module.ts b/dashboard/menu/menu.module.ts index db77cef3..53e90331 100644 --- a/dashboard/menu/menu.module.ts +++ b/dashboard/menu/menu.module.ts @@ -18,8 +18,9 @@ import {LogoUrlPipeModule} from '../../utils/pipes/logoUrlPipe.module'; @NgModule({ imports: [ + MenuRoutingModule, CommonModule, RouterModule, FormsModule, AdminToolServiceModule, - AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, MenuRoutingModule, SearchInputModule, IconsModule, LoadingModule, + AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, InputModule, PageContentModule, AdminTabsModule, SearchInputModule, IconsModule, LoadingModule, TransitionGroupModule, LogoUrlPipeModule ], declarations: [MenuComponent], diff --git a/dashboard/page/pages.module.ts b/dashboard/page/pages.module.ts index 111f1af4..369723fb 100644 --- a/dashboard/page/pages.module.ts +++ b/dashboard/page/pages.module.ts @@ -20,8 +20,9 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module"; @NgModule({ imports: [ + PagesRoutingModule, CommonModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, - MatAutocompleteModule, MatFormFieldModule, MatChipsModule, AdminTabsModule, PageContentModule, PagesRoutingModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule + MatAutocompleteModule, MatFormFieldModule, MatChipsModule, AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule, LogoUrlPipeModule ], declarations: [PagesComponent], exports: [PagesComponent] diff --git a/dashboard/portal/portals.module.ts b/dashboard/portal/portals.module.ts index 3c6ff447..50aaf92b 100644 --- a/dashboard/portal/portals.module.ts +++ b/dashboard/portal/portals.module.ts @@ -15,9 +15,10 @@ import {LoadingModule} from "../../utils/loading/loading.module"; @NgModule({ imports: [ + PortalsRoutingModule, CommonModule, FormsModule, AlertModalModule, ReactiveFormsModule, - RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, PortalsRoutingModule, IconsModule, SearchInputModule, LoadingModule + RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, IconsModule, SearchInputModule, LoadingModule ], declarations: [PortalsComponent], exports: [PortalsComponent] diff --git a/dashboard/sharedComponents/sidebar/layout.service.ts b/dashboard/sharedComponents/sidebar/layout.service.ts index 17657431..dc515f81 100644 --- a/dashboard/sharedComponents/sidebar/layout.service.ts +++ b/dashboard/sharedComponents/sidebar/layout.service.ts @@ -88,6 +88,10 @@ export class LayoutService { * Handle it manually in the component, it doesn't use data * */ private rootClassSubject: BehaviorSubject = new BehaviorSubject(null); + /** + * Display help pop-up on non-admin pages. (default true for the rest of the pages) + * */ + private hasHelpPopUpSubject: BehaviorSubject = new BehaviorSubject(true); private subscriptions: any[] = []; ngOnDestroy() { @@ -343,4 +347,12 @@ export class LayoutService { this.rootClassSubject.next(value); } } + + get hasHelpPopUp(): Observable { + return this.hasHelpPopUpSubject.asObservable(); + } + + setHasHelpPopUp(value: boolean) { + this.hasHelpPopUpSubject.next(value); + } } diff --git a/dashboard/users/role-users/role-users.component.html b/dashboard/users/role-users/role-users.component.html index 6fb1d94f..88befe57 100644 --- a/dashboard/users/role-users/role-users.component.html +++ b/dashboard/users/role-users/role-users.component.html @@ -8,26 +8,26 @@
+ [searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + stakeholderUtils.roles[role] + 's'" searchInputClass="outer">
-
diff --git a/fos/fos.module.ts b/fos/fos.module.ts index d0f1f833..9264a6e9 100644 --- a/fos/fos.module.ts +++ b/fos/fos.module.ts @@ -2,13 +2,11 @@ import {CommonModule} from "@angular/common"; import {NgModule} from "@angular/core"; import {FormsModule} from "@angular/forms"; import {RouterModule} from "@angular/router"; -import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard"; import {IconsModule} from "../utils/icons/icons.module"; import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module"; import {SearchInputModule} from "../sharedComponents/search-input/search-input.module"; import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module"; -import {PiwikService} from "../utils/piwik/piwik.service"; import {FosRoutingModule} from './fos-routing.module'; import {FosComponent} from './fos.component'; @@ -22,9 +20,7 @@ import {FosComponent} from './fos.component'; declarations: [ FosComponent ], - providers: [ - PreviousRouteRecorder, PiwikService - ], + providers: [], exports: [ FosComponent ] diff --git a/landingPages/dataProvider/dataProvider-routing.module.ts b/landingPages/dataProvider/dataProvider-routing.module.ts new file mode 100644 index 00000000..fb878479 --- /dev/null +++ b/landingPages/dataProvider/dataProvider-routing.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { PreviousRouteRecorder } from "../../utils/piwik/previousRouteRecorder.guard"; +import { DataProviderComponent } from "./dataProvider.component"; + + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '', component: DataProviderComponent, canDeactivate: [PreviousRouteRecorder] }]) + ] +}) +export class DataProviderRoutingModule { } diff --git a/landingPages/dataProvider/dataProvider.module.ts b/landingPages/dataProvider/dataProvider.module.ts index 6cbdf9b4..c6716f47 100644 --- a/landingPages/dataProvider/dataProvider.module.ts +++ b/landingPages/dataProvider/dataProvider.module.ts @@ -36,10 +36,12 @@ import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.modu import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-screen-modal.module'; import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; +import {DataProviderRoutingModule} from "./dataProvider-routing.module"; @NgModule({ imports: [CommonModule, FormsModule, RouterModule, + DataProviderRoutingModule, IFrameModule, ErrorMessagesModule, LandingModule, DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule, PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule, diff --git a/landingPages/landing-utils/availableOn.component.ts b/landingPages/landing-utils/availableOn.component.ts index 4a6d28f6..85fef1ea 100644 --- a/landingPages/landing-utils/availableOn.component.ts +++ b/landingPages/landing-utils/availableOn.component.ts @@ -22,7 +22,7 @@ import {RouterHelper} from "../../utils/routerHelper.class"; - -
+
Full-Text: diff --git a/landingPages/landing-utils/entity-metadata.component.ts b/landingPages/landing-utils/entity-metadata.component.ts index d9e0cf98..d27eb26e 100644 --- a/landingPages/landing-utils/entity-metadata.component.ts +++ b/landingPages/landing-utils/entity-metadata.component.ts @@ -89,7 +89,7 @@ import {RouterHelper} from "../../utils/routerHelper.class"; - {{status}} + {{status}} (M{{calcCurrentMonth}}) {{date | date: 'dd MMM yyyy': 'UTC'}} @@ -118,8 +118,9 @@ import {RouterHelper} from "../../utils/routerHelper.class"; - - + + Compatibility: + @@ -137,10 +138,11 @@ import {RouterHelper} from "../../utils/routerHelper.class"; {{compatibility.name}} - - - {{compatibilityString}} - + + + Compatibility: + {{compatibilityString}} + OpenAIRE Text Mining @@ -152,9 +154,9 @@ import {RouterHelper} from "../../utils/routerHelper.class"; Publicly funded - - {{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}} + + Funded by: + {{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}} +{{projects.length - projectsLimit | number}} projects @@ -166,9 +168,9 @@ import {RouterHelper} from "../../utils/routerHelper.class"; - - {{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}} + + Partners: + {{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}} +{{organizations.length - organizationsLimit | number}} partners @@ -180,9 +182,10 @@ import {RouterHelper} from "../../utils/routerHelper.class"; - + {{subjects.slice(0, 3).join(', ')}} + {{provenanceAction}} @@ -292,7 +295,7 @@ export class EntityMetadataComponent { return this.projects.map(project => { let value = project.funderShortname ? project.funderShortname : project.funderName; if (project.acronym || project.title) { - value = value + ' | ' + (project.acronym ? project.acronym : + value = (value ? value + ' | ' : '') + (project.acronym ? project.acronym : (project.title.length > 25 ? (project.title.slice(0, 25) + '...'): project.title)); } // if(project.code) { @@ -361,4 +364,18 @@ export class EntityMetadataComponent { this.projectsModal.open(); } } + + public get calcCurrentMonth() { + let currentDate = new Date(this.currentDate); + let startDate = new Date(this.startDate); + + var months; + months = (currentDate.getFullYear() - startDate.getFullYear()) * 12; + months -= startDate.getMonth(); + months += currentDate.getMonth(); + if(startDate.getDate() > currentDate.getDate()) { + months--; + } + return months <= 0 ? 0 : months+1; + } } \ No newline at end of file diff --git a/landingPages/landing-utils/fundedBy.component.ts b/landingPages/landing-utils/fundedBy.component.ts index c03a5ea1..b7852a4a 100644 --- a/landingPages/landing-utils/fundedBy.component.ts +++ b/landingPages/landing-utils/fundedBy.component.ts @@ -20,14 +20,16 @@ import {RouterHelper} from "../../utils/routerHelper.class";
- +
- + + +
, @@ -35,13 +37,13 @@ import {RouterHelper} from "../../utils/routerHelper.class";
- + -
- +
+
@@ -54,7 +56,7 @@ import {RouterHelper} from "../../utils/routerHelper.class"; | {{ item['acronym'] ? item['acronym'] : item['title']}} - +
Project
@@ -84,7 +86,7 @@ import {RouterHelper} from "../../utils/routerHelper.class"; Funding stream: {{item.funding}} -
+
Validated by funder | {{item.provenanceAction}} @@ -105,8 +107,15 @@ export class FundedByComponent { public url = properties.searchLinkToProject.split('?')[0]; public title: string = "Funded by"; @Input() provenanceActionVocabulary = null; - public provenancesCalculated: boolean[] = []; + // public provenancesCalculated: boolean[] = []; public routerHelper:RouterHelper = new RouterHelper(); + public dropClicked: boolean = false; + + public ngOnInit() { + this.fundedByProjects.forEach((project, index) => { + this.getVocabularyLabel(project, this.provenanceActionVocabulary, index); + }) + } public viewAllClick() { if(this.fundedByProjects.length <= this.threshold*2) { @@ -124,11 +133,11 @@ export class FundedByComponent { } public getVocabularyLabel(item: any, vocabulary: any, index: number) { - if(!this.provenancesCalculated[index]) { - this.provenancesCalculated[index] = true; + // if(!this.provenancesCalculated[index]) { + // this.provenancesCalculated[index] = true; item.provenanceAction = HelperFunctions.getVocabularyLabel(item.provenanceAction, vocabulary, false); - } - return item.provenanceAction; + // } + // return item.provenanceAction; } public addEoscPrevInParams(obj) { diff --git a/landingPages/landing-utils/landing.module.ts b/landingPages/landing-utils/landing.module.ts index a7ae76f1..d97b32a0 100644 --- a/landingPages/landing-utils/landing.module.ts +++ b/landingPages/landing-utils/landing.module.ts @@ -5,24 +5,19 @@ import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { RouterModule } from '@angular/router'; -import {TabPagingComponent} from './tabPaging.component'; import {ShowTitleComponent} from './showTitle.component'; import {AddThisComponent} from './addThis.component'; -import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; -import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard'; @NgModule({ imports: [ - CommonModule, FormsModule, RouterModule, PiwikServiceModule + CommonModule, FormsModule, RouterModule ], declarations: [ - TabPagingComponent, ShowTitleComponent, AddThisComponent + ShowTitleComponent, AddThisComponent ], - providers:[ - PreviousRouteRecorder - ], + providers:[], exports: [ - TabPagingComponent, ShowTitleComponent, AddThisComponent + ShowTitleComponent, AddThisComponent ] }) export class LandingModule { } diff --git a/landingPages/landing-utils/parsingFunctions.class.ts b/landingPages/landing-utils/parsingFunctions.class.ts index 105c54cf..26c1f9d0 100644 --- a/landingPages/landing-utils/parsingFunctions.class.ts +++ b/landingPages/landing-utils/parsingFunctions.class.ts @@ -42,7 +42,7 @@ export class ParsingFunctions { "funderShortname": "", "funderName": "", "funding": "", "code": "", "provenanceAction": "", "validated": false }; - + if (relation.title != 'unidentified') { fundedByProject['id'] = relation['to'].content; fundedByProject['acronym'] = relation.acronym; @@ -538,7 +538,8 @@ export class ParsingFunctions { if (pid.hasOwnProperty("classid") && pid['classid'] != "") { if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data" - || pid.classid == "swhid") { + || pid.classid == "swhid" + || pid.classid == "ROR" || pid.classid == "ISNI" || pid.classid == "Wikidata" || pid.classid == "FundRef") { if (!identifiers.has(pid.classid)) { identifiers.set(pid.classid, new Array()); } @@ -547,7 +548,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" - || pid[i].classid == "swhid") { + || pid[i].classid == "swhid" + || pid[i].classid == "ROR" || pid[i].classid == "ISNI" || pid[i].classid == "Wikidata" || pid[i].classid == "FundRef") { if (!identifiers.has(pid[i].classid)) { identifiers.set(pid[i].classid, new Array()); } @@ -579,7 +581,7 @@ export class ParsingFunctions { return eoscSubjectsFound; } - + // publication & dataset landing : for subjects and otherSubjects and classifiedSubjects parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map, Map, string[], string[],] { // let eoscSubjectsFound = []; @@ -588,12 +590,12 @@ export class ParsingFunctions { let classifiedSubjects: Map; let fos: string[]; let sdg: string[]; - + let setOfEoscSubjects: Set = new Set(); - + let subject; let length = Array.isArray(_subjects) ? _subjects.length : 1; - + for (let i = 0; i < length; i++) { subject = Array.isArray(_subjects) ? _subjects[i] : _subjects; if (subject.classid != "") { @@ -626,7 +628,7 @@ export class ParsingFunctions { if (classifiedSubjects == undefined) { classifiedSubjects = new Map(); } - + let content: string = subject.content + ""; // let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content); // let found: boolean = checkAndAddEoscSubjectResp["found"]; @@ -637,7 +639,11 @@ export class ParsingFunctions { if (!classifiedSubjects.has(subject.classname)) { classifiedSubjects.set(subject.classname, new Array()); } - classifiedSubjects.get(subject.classname).push(content); + if(properties.environment == "production") { + classifiedSubjects.get(subject.classname).push(content); + } else { + classifiedSubjects.get(subject.classname).push(subject.classid + ": " + content); + } // } } } else { @@ -657,6 +663,14 @@ export class ParsingFunctions { } } } + + if(properties.environment != "production" && classifiedSubjects != null) { + for (let classified of classifiedSubjects.keys()) { + subjects = subjects.concat(classifiedSubjects.get(classified)); + } + classifiedSubjects = null; + } + return [subjects, otherSubjects, classifiedSubjects, fos, sdg]; } diff --git a/landingPages/landing-utils/sdg-fos-suggest/sdg-fos-suggest.component.ts b/landingPages/landing-utils/sdg-fos-suggest/sdg-fos-suggest.component.ts index 6c0d059a..3a547a27 100644 --- a/landingPages/landing-utils/sdg-fos-suggest/sdg-fos-suggest.component.ts +++ b/landingPages/landing-utils/sdg-fos-suggest/sdg-fos-suggest.component.ts @@ -15,34 +15,36 @@ import {StringUtils} from "../../../utils/string-utils.class"; template: ` - - -
-
- -
Thank you for your feedback.
-
Before sending us your options, would you like to leave us your e-mail to notify you about the reporting status?
-
- (Optional) + + + +
+
+ +
Thank you for your feedback.
+
Before sending us your options, would you like to leave us your e-mail to notify you about the reporting status?
+
+ (Optional) +
+
+ + +
+
+ +

Your feedback is successfully received and it will soon be reviewed by our graph experts!

+ +
+ -
- - -
- - -

Your feedback is successfully received and it will soon be reviewed by our graph experts!

- -
-
-
+
` }) @@ -62,6 +64,7 @@ export class SdgFosSuggestComponent { public sent: boolean = false; public error: boolean = false; subscriptions: Subscription[] = []; + isOpen: boolean = false; constructor(private emailService: EmailService, private fb: FormBuilder, private cdr: ChangeDetectorRef) {} diff --git a/landingPages/landing-utils/showIdentifiers.component.ts b/landingPages/landing-utils/showIdentifiers.component.ts index 8a0b4680..11a15f14 100644 --- a/landingPages/landing-utils/showIdentifiers.component.ts +++ b/landingPages/landing-utils/showIdentifiers.component.ts @@ -26,8 +26,9 @@ import {properties} from "../../../../environments/environment"; {{key}}: - + {{item}} , @@ -113,7 +114,10 @@ export class ShowIdentifiersComponent implements AfterViewInit { }); } - public getUrl(key: string): string { + public getUrl(key: string, value: string): string { + if(value.includes("http://") || value.includes("https://")) { + return ""; + } if(key == "doi") { return properties.doiURL; } else if(key == "pmc") { @@ -126,6 +130,14 @@ export class ShowIdentifiersComponent implements AfterViewInit { return properties.r3DataURL; } else if(key == "swhid") { return properties.swhURL; + } else if(key == "ROR") { + return properties.rorURL; + } else if(key == "ISNI") { + return properties.isniURL; + } else if(key == "Wikidata") { + return properties.wikiDataURL; + } else if(key == "FundRef") { + return properties.fundRefURL; } } diff --git a/landingPages/landing-utils/showPublisher.component.ts b/landingPages/landing-utils/showPublisher.component.ts index 37c0838b..bbb8c177 100644 --- a/landingPages/landing-utils/showPublisher.component.ts +++ b/landingPages/landing-utils/showPublisher.component.ts @@ -5,7 +5,8 @@ import {EnvProperties} from "../../utils/properties/env-properties"; selector: 'showPublisher, [showPublisher]', template: ` - {{publisher}} + Publisher: + {{publisher}} @@ -14,7 +15,8 @@ import {EnvProperties} from "../../utils/properties/env-properties"; || journal['volume'] || journal['eissn'] || journal['issue'])"> - + + Journal: {{journal['journal']}} , diff --git a/landingPages/landing-utils/tabPaging.component.ts b/landingPages/landing-utils/tabPaging.component.ts deleted file mode 100644 index 1eb6bd08..00000000 --- a/landingPages/landing-utils/tabPaging.component.ts +++ /dev/null @@ -1,24 +0,0 @@ -import {Component, Input, Output, EventEmitter} from '@angular/core'; - -@Component({ - selector: 'tabPaging', - template: ` - - ` - }) - -export class TabPagingComponent { - @Input() showAll: boolean; - @Input() length: number; - @Output() changeShowAll: EventEmitter = new EventEmitter(); - - constructor () { - } - - ngOnInit() { - } -} diff --git a/landingPages/organization/deletedByInference/deletedByInference.module.ts b/landingPages/organization/deletedByInference/deletedByInference.module.ts index c327c902..eb09712b 100644 --- a/landingPages/organization/deletedByInference/deletedByInference.module.ts +++ b/landingPages/organization/deletedByInference/deletedByInference.module.ts @@ -18,7 +18,7 @@ import {ResultPreviewModule} from "../../../utils/result-preview/result-preview. @NgModule({ imports: [ CommonModule, FormsModule, ResultLandingUtilsModule, - PagingModule, ErrorMessagesModule, ShowAuthorsModule, LandingModule, NoLoadPaging, ResultPreviewModule + PagingModule, ErrorMessagesModule, ShowAuthorsModule, NoLoadPaging, ResultPreviewModule ], declarations: [ OrganizationsDeletedByInferenceComponent diff --git a/landingPages/organization/organization-routing.module.ts b/landingPages/organization/organization-routing.module.ts new file mode 100644 index 00000000..4e48b2b8 --- /dev/null +++ b/landingPages/organization/organization-routing.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { PreviousRouteRecorder } from "../../utils/piwik/previousRouteRecorder.guard"; +import { OrganizationComponent } from "./organization.component"; + + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '', component: OrganizationComponent, canDeactivate: [PreviousRouteRecorder] }]) + ] +}) +export class OrganizationRoutingModule { } diff --git a/landingPages/organization/organization.component.html b/landingPages/organization/organization.component.html index 04f4235a..09f004f2 100644 --- a/landingPages/organization/organization.component.html +++ b/landingPages/organization/organization.component.html @@ -19,57 +19,28 @@
- - -
-
-
- - - Powered by OpenAIRE graph - - - Last update of records in OpenAIRE: {{indexUpdateDate | date: 'MMM dd, yyyy'}} - +
+
+ + + Powered by OpenAIRE graph + + + Last update of records in OpenAIRE: {{indexUpdateDate | date: 'MMM dd, yyyy'}} + - -
- Found an issue? - Give us feedback -
-
-
+ +
+ Found an issue? + Give us feedback +
+
+
- -
- - -
- - + Country: {{organizationInfo.country}}
+ +
+ +
@@ -257,9 +207,7 @@
-
- -
+ @@ -270,12 +218,12 @@
+ + +
- - -
@@ -287,6 +235,23 @@ && organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null" [entityType]="'organization'" [prevPath]="prevPath"> +
+ + + +
+ Country: {{organizationInfo.country}} +
+ +
+ +
+

@@ -406,10 +371,7 @@ [type]="'organizations'" [prevPath]="prevPath"> - - - - +
diff --git a/landingPages/organization/organization.component.ts b/landingPages/organization/organization.component.ts index 814d7bb9..f313a196 100644 --- a/landingPages/organization/organization.component.ts +++ b/landingPages/organization/organization.component.ts @@ -77,7 +77,6 @@ export class OrganizationComponent { @ViewChild('downloadReportsFsModal') downloadReportsFsModal: FullScreenModalComponent; // @ViewChild('downloadReportModal') downloadReportModal; // @ViewChild('downloadFunderReportModal') downloadFunderReportModal; - @ViewChild('addThisModal') addThisModal; @ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent; @ViewChild(ModalLoading) loading: ModalLoading; @@ -717,13 +716,6 @@ export class OrganizationComponent { this.downloadReportsModal.cancel(); } - public openAddThisModal() { - this.addThisModal.cancelButton = false; - this.addThisModal.okButton = false; - this.addThisModal.alertTitle = "Share this "+OpenaireEntities.ORGANIZATION+" in your social networks"; - this.addThisModal.open(); - } - public getParamsForSearchLink(type: string = "") { if(type) { return this.routerHelper.createQueryParams(['f0', 'fv0', 'type', 'qf', 'sortBy'], ['relorganizationid', this.organizationId, type, 'false', 'resultdateofacceptance,descending']); diff --git a/landingPages/organization/organization.module.ts b/landingPages/organization/organization.module.ts index 9a4a2737..c7b2d24c 100644 --- a/landingPages/organization/organization.module.ts +++ b/landingPages/organization/organization.module.ts @@ -33,11 +33,14 @@ import {graph, versions} from "../../utils/icons/icons"; import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module"; import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module"; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; +import {OrganizationRoutingModule} from "./organization-routing.module"; +import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module"; @NgModule({ imports: [ CommonModule, FormsModule, RouterModule, + OrganizationRoutingModule, LoadingModalModule, AlertModalModule, ErrorMessagesModule, LandingModule, DataProvidersServiceModule, @@ -49,7 +52,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod ProjectsServiceModule, Schema2jsonldModule, SEOServiceModule, HelperModule, OrganizationsDeletedByInferenceModule, LandingHeaderModule, FeedbackModule, - TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule, FullScreenModalModule, EGIDataTransferModule, EntityActionsModule + TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule, FullScreenModalModule, EntityActionsModule, ResultLandingUtilsModule ], declarations: [ OrganizationComponent, diff --git a/landingPages/project/project-routing.module.ts b/landingPages/project/project-routing.module.ts new file mode 100644 index 00000000..3cec4ec2 --- /dev/null +++ b/landingPages/project/project-routing.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import { PreviousRouteRecorder } from "../../utils/piwik/previousRouteRecorder.guard"; +import { ProjectComponent } from "./project.component"; + + +@NgModule({ + imports: [ + RouterModule.forChild([{ path: '', component: ProjectComponent, canDeactivate: [PreviousRouteRecorder] }]) + ] +}) +export class ProjectRoutingModule { } diff --git a/landingPages/project/project.module.ts b/landingPages/project/project.module.ts index 713c9f1f..b2d6d649 100644 --- a/landingPages/project/project.module.ts +++ b/landingPages/project/project.module.ts @@ -32,9 +32,11 @@ import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-sc import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module"; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; +import {ProjectRoutingModule} from "./project-routing.module"; @NgModule({ imports: [ + ProjectRoutingModule, CommonModule, FormsModule, RouterModule, LandingModule, LoadingModalModule, AlertModalModule, ErrorMessagesModule, IFrameModule, ReportsServiceModule, diff --git a/landingPages/result/deletedByInference/deletedByInference.component.ts b/landingPages/result/deletedByInference/deletedByInference.component.ts index 69a47dab..b986c240 100644 --- a/landingPages/result/deletedByInference/deletedByInference.component.ts +++ b/landingPages/result/deletedByInference/deletedByInference.component.ts @@ -27,8 +27,8 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
  • + [showOrcid]="false" [prevPath]="prevPath" [showInline]="true" + [isDeletedByInferenceModal]="true" [isMobile]="isMobile">
-
-
+
+
- - - -
@@ -143,7 +79,8 @@ [type]="resultLandingInfo.resultType" [result]="resultLandingInfo" [id]="resultLandingInfo.objIdentifier"> -
@@ -166,54 +103,6 @@
- - -
- - - - - - - -
- - -
-
- -
-
@@ -232,48 +121,15 @@ [publiclyFunded]="resultLandingInfo.publiclyFunded" [projects]="resultLandingInfo.fundedByProjects"> - - -
- - -
- -
+ +
-
- - - - - -
-
- -
- -
-
-
-
-
+
- -
@@ -711,7 +545,8 @@

- +
- + - + + + -
+
@@ -1327,23 +1164,32 @@
+ + [resultType]="type" [type]="openaireEntities.PUBLICATIONS" + [isMobile]="isMobile" + [modal]="alertModalDeletedByInferenceFS"> + [resultType]="'dataset'" [type]="openaireEntities.DATASETS" + [isMobile]="isMobile" + [modal]="alertModalDeletedByInferenceFS"> + [resultType]="type" [type]="openaireEntities.SOFTWARE" + [isMobile]="isMobile" + [modal]="alertModalDeletedByInferenceFS"> + [resultType]="'other'" [type]="openaireEntities.OTHER" + [isMobile]="isMobile" + [modal]="alertModalDeletedByInferenceFS"> @@ -1352,5 +1198,6 @@ - + + \ No newline at end of file diff --git a/landingPages/result/resultLanding.component.ts b/landingPages/result/resultLanding.component.ts index f51645f3..769f1975 100644 --- a/landingPages/result/resultLanding.component.ts +++ b/landingPages/result/resultLanding.component.ts @@ -74,6 +74,8 @@ export class ResultLandingComponent { public linkToSearchPage: string = null; public citeThisClicked: boolean; + public addThisClicked: boolean; + public descriptionClicked: boolean; // Metrics tab variables public metricsClicked: boolean; @@ -197,6 +199,9 @@ export class ResultLandingComponent { private userManagementService: UserManagementService, private layoutService: LayoutService, private _contextService: ContextsService) { + if(route.snapshot.data && route.snapshot.data['type']) { + this.type = route.snapshot.data['type']; + } } ngOnInit() { @@ -864,6 +869,7 @@ export class ResultLandingComponent { } public openAddThisModal() { + this.addThisClicked = true; this.addThisModal.cancelButton = false; this.addThisModal.okButton = false; this.addThisModal.alertTitle = "Share this " + this.getTypeName() + " in your social networks"; @@ -1076,6 +1082,7 @@ export class ResultLandingComponent { this.sdgFosSuggest.subjectType="fos"; } this.cdr.detectChanges(); + this.sdgFosSuggest.isOpen = true; this.sdgFosSuggest.openSelectionModal(); } @@ -1090,6 +1097,7 @@ export class ResultLandingComponent { } public openDescriptionModal() { + this.descriptionClicked = true; this.descriptionModal.alertFooter = false; this.descriptionModal.alertTitle = "Abstract"; this.descriptionModal.open(); diff --git a/landingPages/result/resultLanding.module.ts b/landingPages/result/resultLanding.module.ts index 247c8a99..d1792e55 100644 --- a/landingPages/result/resultLanding.module.ts +++ b/landingPages/result/resultLanding.module.ts @@ -26,7 +26,6 @@ import {ResultPreviewModule} from "../../utils/result-preview/result-preview.mod import {FeedbackModule} from "../feedback/feedback.module"; import {TabsModule} from "../../utils/tabs/tabs.module"; import {LoadingModule} from "../../utils/loading/loading.module"; -import {OrcidModule} from "../../orcid/orcid.module"; import {IconsModule} from "../../utils/icons/icons.module"; import {IconsService} from "../../utils/icons/icons.service"; import {cite, fire, graph, landmark, link, link_to, quotes, rocket, versions} from "../../utils/icons/icons"; @@ -37,15 +36,19 @@ import {SdgFosSuggestModule} from '../landing-utils/sdg-fos-suggest/sdg-fos-sugg import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module"; import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; +import {ResultLandingRoutingModule} from "./resultLanding-routing.module"; +import {OrcidCoreModule} from "../../orcid/orcid-core.module"; +import {SearchTabModule} from "../../utils/tabs/contents/search-tab.module"; @NgModule({ imports: [ CommonModule, FormsModule, LandingModule, SharedModule, RouterModule, + ResultLandingRoutingModule, CiteThisModule, PagingModule, IFrameModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule, DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule, - OrcidModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule, + OrcidCoreModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule, SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule ], declarations: [ diff --git a/login/freeGuard.guard.ts b/login/freeGuard.guard.ts index 13d5941e..9d2b2b0c 100644 --- a/login/freeGuard.guard.ts +++ b/login/freeGuard.guard.ts @@ -3,7 +3,7 @@ import { Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@a import {Observable} from 'rxjs'; import {LoginErrorCodes} from './utils/guardHelper.class'; -@Injectable() +@Injectable({providedIn: 'root'}) export class FreeGuard { constructor(private router: Router) { diff --git a/login/user.module.ts b/login/user.module.ts index f592e6b8..13e493d6 100644 --- a/login/user.module.ts +++ b/login/user.module.ts @@ -7,16 +7,13 @@ import {UserRoutingModule} from './user-routing.module'; import {UserComponent} from './user.component'; -import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; import {LoadingModule} from "../utils/loading/loading.module"; @NgModule({ imports: [ CommonModule, FormsModule, UserRoutingModule, RouterModule, LoadingModule ], - providers: [ - PreviousRouteRecorder - ], + providers: [], declarations: [ UserComponent ], diff --git a/login/utils/helper.class.ts b/login/utils/helper.class.ts index 92c2a62e..152cda48 100644 --- a/login/utils/helper.class.ts +++ b/login/utils/helper.class.ts @@ -234,12 +234,13 @@ export class Role { } public static mapType(type: string, communityMap: boolean = true): string { + type = type.replace(this.GROUP, ''); if (type == "ri" && communityMap) { type = "community"; } else if (type == "organization") { type = "institution"; } - return Role.GROUP + type; + return type; } /** diff --git a/monitor-admin/general/edit-stakeholder/edit-stakeholder.component.ts b/monitor-admin/general/edit-stakeholder/edit-stakeholder.component.ts index 72be3c8a..05eafbd5 100644 --- a/monitor-admin/general/edit-stakeholder/edit-stakeholder.component.ts +++ b/monitor-admin/general/edit-stakeholder/edit-stakeholder.component.ts @@ -20,7 +20,7 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component"; template: `
-
+
@@ -126,6 +126,19 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
+
+
Instance Type
+
+ + +
+
{ this.user = user; if (this.isCurator) { @@ -220,6 +235,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent { funderType: this.fb.control(this.stakeholder.funderType), topics: this.fb.control(this.stakeholder.topics), isUpload: this.fb.control(this.stakeholder.isUpload), + copy: this.fb.control(this.stakeholder.copy), logoUrl: this.fb.control(this.stakeholder.logoUrl), }); if (this.stakeholder.isUpload) { @@ -246,7 +262,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent { this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => { this.onTypeChange(value, defaultStakeholders); })); - this.stakeholderFb.setControl('defaultId', this.fb.control(stakeholder.defaultId, (this.isDefault && !this.isNew) ? [] : Validators.required)); + this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew) ? [] : Validators.required)); if (!this.isNew) { this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); this.notify.reset(this.notification.message); @@ -304,6 +320,13 @@ export class EditStakeholderComponent extends StakeholderBaseComponent { return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions; } + public get canChangeCopy(): boolean { + return this.isCurator && + !this.stakeholderFb.get('isDefault').getRawValue() && + this.stakeholderFb.get('defaultId').getRawValue() && + this.stakeholderFb.get('defaultId').getRawValue() !== '-1'; + } + reset() { this.uploadError = null; this.stakeholderFb = null; @@ -350,15 +373,15 @@ export class EditStakeholderComponent extends StakeholderBaseComponent { public saveStakeholder(callback: Function, errorCallback: Function = null) { if (this.isNew) { - let defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId); - this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(), - (defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault)); - this.removePhoto(); + let copyId = null; if (this.stakeholderFb.getRawValue().isDefault) { + copyId = this.stakeholderFb.getRawValue().defaultId !== '-1'?this.stakeholderFb.getRawValue().defaultId:null; this.stakeholderFb.get('defaultId').setValue(null); + this.stakeholderFb.removeControl('isDefault'); } + this.removePhoto(); this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, - this.stakeholderFb.getRawValue()).subscribe(stakeholder => { + this.stakeholderFb.getRawValue(), copyId).subscribe(stakeholder => { this.notification.entity = stakeholder._id; this.notification.stakeholder = stakeholder.alias; this.notification.stakeholderType = stakeholder.type; @@ -375,7 +398,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent { this.loading = false; })); } else { - this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue()).subscribe(stakeholder => { + this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.getRawValue(), [], this.isFull).subscribe(stakeholder => { this.notification.entity = stakeholder._id; this.notification.stakeholder = stakeholder.alias; this.notification.stakeholderType = stakeholder.type; diff --git a/monitor-admin/general/edit-stakeholder/edit-stakeholder.module.ts b/monitor-admin/general/edit-stakeholder/edit-stakeholder.module.ts index 0ebec4d3..5e325317 100644 --- a/monitor-admin/general/edit-stakeholder/edit-stakeholder.module.ts +++ b/monitor-admin/general/edit-stakeholder/edit-stakeholder.module.ts @@ -5,9 +5,10 @@ import {InputModule} from "../../../sharedComponents/input/input.module"; import {ReactiveFormsModule} from "@angular/forms"; import {IconsModule} from "../../../utils/icons/icons.module"; import {NotifyFormModule} from "../../../notifications/notify-form/notify-form.module"; +import {MatSlideToggleModule} from "@angular/material/slide-toggle"; @NgModule({ - imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule], + imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule, MatSlideToggleModule], declarations: [EditStakeholderComponent], exports: [EditStakeholderComponent] }) diff --git a/monitor-admin/general/general.component.ts b/monitor-admin/general/general.component.ts index fda34d94..2f28f504 100644 --- a/monitor-admin/general/general.component.ts +++ b/monitor-admin/general/general.component.ts @@ -48,7 +48,7 @@ export class GeneralComponent extends BaseComponent implements OnInit { } public reset() { - this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, this.stakeholder.defaultId == null, false) + this.editStakeholderComponent.init(this.stakeholder, this.alias, this.defaultStakeholders, this.stakeholder.defaultId == null, false, true) } public save() { diff --git a/monitor-admin/general/general.module.ts b/monitor-admin/general/general.module.ts index 7f4e7064..8f4aef96 100644 --- a/monitor-admin/general/general.module.ts +++ b/monitor-admin/general/general.module.ts @@ -1,7 +1,6 @@ import {NgModule} from "@angular/core"; import {GeneralComponent} from "./general.component"; import {GeneralRoutingModule} from "./general-routing.module"; -import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard"; import {CommonModule} from "@angular/common"; import {RouterModule} from "@angular/router"; import {InputModule} from "../../sharedComponents/input/input.module"; @@ -30,9 +29,7 @@ import { LogoUrlPipeModule, SidebarMobileToggleModule ], - providers: [ - PreviousRouteRecorder, - ], + providers: [], exports: [GeneralComponent] }) export class GeneralModule { diff --git a/monitor-admin/manageStakeholders/manageStakeholders.component.html b/monitor-admin/manageStakeholders/manageStakeholders.component.html index cf96dbc3..c96d3f63 100644 --- a/monitor-admin/manageStakeholders/manageStakeholders.component.html +++ b/monitor-admin/manageStakeholders/manageStakeholders.component.html @@ -12,14 +12,13 @@
-
-
-
+
+
-
@@ -32,7 +31,7 @@
-
+

Profile Templates

-
+
@@ -60,7 +58,7 @@
-
+

Profiles

-
-
Number Indicators
-
-
-
-
-
- - - - - - - - - - - - - - - - -
-
-
-
-
-
- -
-
-
- - - - -
- +
+ +
+ -
-
{{indicator.name}}
-
- - -- -
-
- -
- +
+ +
-
-
- -
-
-
-
Chart Indicators
-
-
-
-
-
- - - - - - - - - - - - - - - - -
-
-
-
-
-
- -
-
-
- - - - -
- +
+
-
-
-
- {{indicator.name}} +
+
+
+
+
+ Create a custom indicator +
+
+ Use our advance tool to create a custom Indicator that suit the needs of your + funding + KPI's. +
+
+ +
+
+
+
- -
- -
-
- -
- -
-
-
-
-
-
-
-
-
- Create a custom indicator -
-
- Use our advance tool to create a custom Indicator that suit the needs of your funding - KPI's. -
-
- -
-
-
-
+
+ +
-
-
- -
-
+
+
+
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{urlParameterizedMessage}}
-
-
- -
-
-
-
- There are schema enhancements that can be applied in this query.Apply - now -
-
-
-
-
-
-
-
-
-
-
-
-
-
- JSON Path -
-
-
- This JSON path is not valid or the result has not been calculated yet. - Please press calculate on box below to see the result. -
-
-
-
-
- - - - - - -
-
- -
-
-
-
-
- - - - - -- - - - -
-
-
-
-
+ [large]="true" classTitle="uk-background-primary uk-light" + (alertOutput)="saveIndicator()" + [okDisabled]="numberIndicatorFb && (numberIndicatorFb.invalid || numberIndicatorFb.pristine)"> +
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ JSON Path +
+
+
+ This JSON path is not valid or the result has not been calculated yet. + Please press calculate on box below to see the result. +
+
+
+
+
+ + + + + + +
+
+ +
+
+
+ +
+
+
+
+
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{urlParameterizedMessage}}
+ [okDisabled]="chartIndicatorFb && (chartIndicatorFb.invalid || chartIndicatorFb.pristine)"> +
+ +
+
+
+
+
-
- +
-
-
-
- There are schema enhancements that can be applied in this query. Apply - now +
-
- -
-
- -
-
- + +
+
+ +
+ You are about to delete + "{{ indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title ? indicator.indicatorPaths[0].parameters.title : '') }} + " indicator permanently. +
+ Indicators of all profiles based on this default indicator, will be deleted as well. +
+ Are you sure you want to proceed? +
- You are about to delete - "{{indicator.name ? indicator.name : (indicator.indicatorPaths[0]?.parameters?.title?indicator.indicatorPaths[0].parameters.title:'')}}" indicator permanently. -
- Indicators of all profiles based on this default indicator, will be deleted as well. -
- - - - Are you sure you want to proceed? -
-
- - -
-
- + +
+
+ +
+ You are about to delete this section and its indicators permanently. +
+ Sections of all profiles based on this default section and their contents, will be deleted as well. +
+ Are you sure you want to proceed?
- You are about to delete this section and its indicators permanently. -
- Sections of all profiles based on this default section and their contents, will be deleted as well. -
- - - - Are you sure you want to proceed? -
- -
-
- +
+
+ +
-
diff --git a/monitor-admin/topic/indicators.component.ts b/monitor-admin/topic/indicators.component.ts index 2d09461d..715fba78 100644 --- a/monitor-admin/topic/indicators.component.ts +++ b/monitor-admin/topic/indicators.component.ts @@ -20,7 +20,7 @@ import { Visibility } from "../../monitor/entities/stakeholder"; import { - AbstractControl, + AbstractControl, FormArray, FormGroup, UntypedFormArray, UntypedFormBuilder, UntypedFormControl, @@ -31,8 +31,8 @@ import {AlertModal} from "../../utils/modal/alert"; import {StatisticsService} from "../utils/services/statistics.service"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser"; -import {Reorder, StakeholderService} from "../../monitor/services/stakeholder.service"; -import {Observable, Subscriber} from "rxjs"; +import {MoveIndicator, SectionInfo, StakeholderService} from "../../monitor/services/stakeholder.service"; +import {BehaviorSubject, Observable, Subscriber} from "rxjs"; import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service"; import {Router} from "@angular/router"; import {Role, Session, User} from "../../login/utils/helper.class"; @@ -44,6 +44,8 @@ import {NotificationService} from "../../notifications/notification.service"; import {NotificationHandler} from "../../utils/notification-handler"; import {IndicatorStakeholderBaseComponent} from "../utils/stakeholder-base.component"; import {properties} from "../../../../environments/environment"; +import {StatsProfilesService} from "../utils/services/stats-profiles.service"; +import {TransitionGroupComponent} from "../../utils/transition-group/transition-group.component"; declare var UIkit; declare var copy; @@ -68,6 +70,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple @Input() public user: User = null; public preview: string; + public statsProfiles = []; public numberIndicatorFb: UntypedFormGroup; public chartIndicatorFb: UntypedFormGroup; public chartSections: UntypedFormArray; @@ -80,12 +83,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public index: number = -1; public editing: boolean = false; public dragging: boolean = false; + /* Reorder indicators */ + public to: BehaviorSubject = new BehaviorSubject(null); /** Caches */ public safeUrls: Map = new Map([]); public numberResponses: Map = new Map(); public numberResults: Map = new Map(); - /** Import / Export Indicators */ - importLoading: boolean = false; + public loading: boolean = false; @ViewChild('editChartModal', {static: true}) editChartModal: AlertModal; @ViewChild('editNumberModal', {static: true}) editNumberModal: AlertModal; @ViewChild('deleteModal', {static: true}) deleteModal: AlertModal; @@ -93,12 +97,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public sectionTypeToDelete: string; public sectionChildrenActionOnDelete: string; public indicatorChildrenActionOnDelete: string; - urlParameterizedMessage = null; - showCheckForSchemaEnhancements: boolean = false; private notification: Notification; @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; @ViewChild('deleteNotify', {static: true}) deleteNotify: NotifyFormComponent; + /* Transition Groups */ + @ViewChild('numbersTransition') numbersTransition: TransitionGroupComponent; + @ViewChild('chartsTransition') chartsTransition: TransitionGroupComponent; public isFullscreen: boolean = false; @@ -119,10 +124,10 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple constructor(private layoutService: LayoutService, private stakeholderService: StakeholderService, private statisticsService: StatisticsService, + private statsProfileService: StatsProfilesService, private notificationService: NotificationService, private fb: UntypedFormBuilder, protected _router: Router, - private cdr: ChangeDetectorRef, private sanitizer: DomSanitizer) { super() this.filesToUpload = []; @@ -137,7 +142,16 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.setCharts(); this.setNumbers(); this.initReorder(); - }) + }); + if (this.isCurator) { + this.subscriptions.push(this.statsProfileService.getStatsProfiles().subscribe(statsProfiles => { + this.statsProfiles = [null].concat(statsProfiles); + }, error => { + this.statsProfiles = []; + })); + } else { + this.statsProfiles = []; + } } ngOnDestroy(): void { @@ -175,7 +189,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } }); if (document !== undefined) { - let callback = (list, type: IndicatorType, action: 'moved' | 'added' | 'removed'): void => { + let callback = (list): string[] => { let items: HTMLCollection = list.current.children; let reordered = []; for (let i = 0; i < items.length; i++) { @@ -183,12 +197,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple reordered.push(items.item(i).id); } } - let reorder: Reorder = { - action: action, - target: list.detail[1].id, - ids: reordered - } - this.reorderIndicators(list.current.id.toString().split('-')[1], type, reorder); + return reordered; }; this.numbers.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'start', '#number-' + section._id, (): void => { @@ -198,24 +207,32 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.dragging = false; })); this.subscriptions.push(UIkit.util.on(document, 'moved', '#number-' + section._id, (list): void => { - callback(list, "number", 'moved'); + this.reorderIndicators(section._id, 'number', callback(list)); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => { - callback(list, "number", 'added'); + this.to.next({id: section._id, indicators: callback(list)}); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => { - callback(list, "number", 'removed'); + let sub = this.to.asObservable().subscribe(to => { + if (to) { + let from: SectionInfo = {id: section._id, indicators: callback(list)}; + this.moveIndicator({target: list.detail[1].id, from: from, to: to}); + setTimeout(() => { + sub.unsubscribe(); + }) + } + }) })); }); this.charts.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'moved'); + this.reorderIndicators(section._id, 'chart', callback(list)); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'added'); + //callback(list, "chart", 'added'); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => { - callback(list, "chart", 'removed'); + // callback(list, "chart", 'removed'); })); }); } @@ -252,7 +269,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple setNumbers() { this.numberSections = this.fb.array([]); this.numberResults.clear(); - let urls: Map = new Map(); + let urls: Map = new Map(); this.numbers.forEach((section, i) => { this.numberSections.push(this.fb.group({ _id: this.fb.control(section._id), @@ -264,11 +281,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple indicators: this.fb.control(section.indicators) })); section.indicators.forEach((number, j) => { - let url = this.indicatorUtils.getFullUrl(this.stakeholder, number.indicatorPaths[0]); - const pair = JSON.stringify([number.indicatorPaths[0].source, url]); - const indexes = urls.get(pair) ? urls.get(pair) : []; - indexes.push([i, j]); - urls.set(pair, indexes); + number.indicatorPaths.forEach((indicatorPath, k) => { + let url = this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath); + const pair = JSON.stringify([indicatorPath.source, url]); + const indexes = urls.get(pair) ? urls.get(pair) : []; + indexes.push([i, j, k]); + urls.set(pair, indexes); + }); }); }); this.numberSubscription.forEach(value => { @@ -290,10 +309,10 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); } - private calculateResults(response: any, indexes: [number, number][]) { - indexes.forEach(([i, j]) => { + private calculateResults(response: any, indexes: [number, number, number][]) { + indexes.forEach(([i, j, k]) => { let result = JSON.parse(JSON.stringify(response)); - this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { + this.numbers[i].indicators[j].indicatorPaths[k].jsonPath.forEach(jsonPath => { if (result) { result = result[jsonPath]; } @@ -306,14 +325,14 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } else { result = 0; } - this.numberResults.set(i + '-' + j, result); + this.numberResults.set(i + '-' + j + '-' + k, result); }); } get charts(): Section[] { if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts; } else { return []; @@ -322,8 +341,8 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple get numbers(): Section[] { if (this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers; } else { return []; @@ -340,9 +359,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple get canEdit() { return this.stakeholder && - this.stakeholder.topics[this.topicIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]; + this.stakeholder.topics[this.topicIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] && !this.loading; } public get numberIndicatorPaths(): UntypedFormArray { @@ -353,6 +372,14 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return this.chartIndicatorFb.get('indicatorPaths') as UntypedFormArray; } + public getActiveIndicatorPath(indicator: Indicator) { + if (indicator.activePath) { + return indicator.indicatorPaths[indicator.activePath]; + } else { + return indicator.indicatorPaths[0]; + } + } + public getNumberClassBySize(size: IndicatorSize) { if (size === 'small') { return 'uk-width-medium@m uk-width-1-1'; @@ -400,7 +427,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.getJsonPath(index).disable(); } indicatorPath.get('result').setErrors({validating: true}); - this.subscriptions.push(this.statisticsService.getNumbers(null, indicatorPath.get('url').value).subscribe(response => { + this.subscriptions.push(this.statisticsService.getNumbers(indicatorPath.get('source').value, this.indicatorUtils.getFullUrl(this.stakeholder, this.indicator.indicatorPaths[index])).subscribe(response => { let result = JSON.parse(JSON.stringify(response)); this.getJsonPath(index).controls.forEach(jsonPath => { if (result) { @@ -448,17 +475,21 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return this.section.indicators[this.index].indicatorPaths[index].jsonPath; } - public getParameters(index: number): UntypedFormArray { - return this.chartIndicatorPaths.at(index).get('parameters') as UntypedFormArray; + public getParameters(index: number, type: IndicatorType = 'chart'): UntypedFormArray { + if (type === 'chart') { + return this.chartIndicatorPaths.at(index).get('parameters') as UntypedFormArray; + } else { + return this.numberIndicatorPaths.at(index).get('parameters') as UntypedFormArray; + } } - public getParameter(index: number, key: string): UntypedFormControl { - return this.getParameters(index).controls.filter(control => control.value.key === key)[0] as UntypedFormControl; + public getParameter(index: number, key: string, type: IndicatorType = 'chart'): UntypedFormControl { + return this.getParameters(index, type).controls.filter(control => control.value.key === key)[0] as UntypedFormControl; } private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.sanitizer.bypassSecurityTrustResourceUrl( - this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); + this.indicatorUtils.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); } private getUrlByStakeHolder(indicatorPath: IndicatorPath) { @@ -470,69 +501,57 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple jsonPath.push(this.fb.control('', Validators.required)); } this.numberIndicatorPaths.push(this.fb.group({ - url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]), - jsonPath: jsonPath, - result: this.fb.control(0, Validators.required), - source: this.fb.control(source, Validators.required), - format: this.fb.control(format, Validators.required) - } + url: this.fb.control(url, [Validators.required, StringUtils.urlValidator()]), + jsonPath: jsonPath, + result: this.fb.control(0, Validators.required), + source: this.fb.control(source, Validators.required), + parameters: parameters, + format: this.fb.control(format, Validators.required) + } )); let index = this.numberIndicatorPaths.length - 1; if (this.numberIndicatorPaths.at(index).get('url').valid) { this.validateJsonPath(index); - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); } if (this.indicator.defaultId === null) { this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { - this.numberIndicatorPaths.at(index).get('result').setValue(null); - if (this.numberIndicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." + this.numberIndicatorPaths.at(index).get('result').setValue(null); + if (this.numberIndicatorPaths.at(index).get('url').valid) { + let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(value), value, this.stakeholder, this.numberIndicatorPaths.at(index).get('jsonPath').value, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(value))); + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index] = indicatorPath; } else { - this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder." + this.indicator.indicatorPaths.push(indicatorPath); } - } else { - this.urlParameterizedMessage = null; - } - this.checkForSchemaEnhancements(this.numberIndicatorPaths.at(index).get('url').value); - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index] = indicatorPath; - } else { - this.indicator.indicatorPaths.push(indicatorPath); - } - if (indicatorPath.source) { - this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source); - } - if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) { - let paths = indicatorPath.jsonPath; - for (let i = 0; i < paths.length; i++) { - if (i == this.getJsonPath(index).length) { - this.getJsonPath(index).push(this.fb.control('', Validators.required)); + if (indicatorPath.source) { + this.numberIndicatorPaths.at(index).get('source').setValue(indicatorPath.source); + } + (this.numberIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); + if (indicatorPath.jsonPath.length > 1 && this.getJsonPath(index).length == 1) { + let paths = indicatorPath.jsonPath; + for (let i = 0; i < paths.length; i++) { + if (i == this.getJsonPath(index).length) { + this.getJsonPath(index).push(this.fb.control('', Validators.required)); + } } + this.getJsonPath(index).setValue(paths) } - this.getJsonPath(index).setValue(paths) } - } else { - this.urlParameterizedMessage = null; - } - }) + }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].jsonPath = value; - } - this.numberIndicatorPaths.at(index).get('result').setValue(null); - }) + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index].jsonPath = value; + } + this.numberIndicatorPaths.at(index).get('result').setValue(null); + }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => { - if (this.indicator.indicatorPaths[index]) { - this.indicator.indicatorPaths[index].source = value; - } - }) + if (this.indicator.indicatorPaths[index]) { + this.indicator.indicatorPaths[index].source = value; + } + }) ); } else { this.numberIndicatorPaths.at(index).get('url').disable(); @@ -543,33 +562,20 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple public addChartIndicatorPath(value: string = '', parameters: UntypedFormArray = new UntypedFormArray([]), disableUrl: boolean = false, type: string = null) { this.chartIndicatorPaths.push(this.fb.group({ - url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]), - parameters: parameters, - type: this.fb.control(type) - } + url: this.fb.control(value, [Validators.required, StringUtils.urlValidator()]), + parameters: parameters, + type: this.fb.control(type) + } )); let index = this.chartIndicatorPaths.length - 1; if (disableUrl) { this.chartIndicatorPaths.at(index).get('url').disable(); } else { - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.chartIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); - if (!this.isStakeholderParametersValid(indicatorPath)) { - // default profile - if (this.stakeholder.defaultId == null) { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." - } else { - this.urlParameterizedMessage = "This chart couldn't be generated properly. Please make sure chart data is for the current stakeholder." - } - } else { - this.urlParameterizedMessage = null; - } - this.checkForSchemaEnhancements(this.chartIndicatorPaths.at(index).get('url').value); (this.chartIndicatorPaths.at(index) as UntypedFormGroup).get('type').setValue(indicatorPath.type); - let parameters = this.getParametersAsFormArray(indicatorPath); - (this.chartIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', parameters); + (this.chartIndicatorPaths.at(index) as UntypedFormGroup).setControl('parameters', this.getParametersAsFormArray(indicatorPath)); if (!this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index] = indicatorPath; this.indicator.indicatorPaths[index].safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); @@ -577,17 +583,73 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple indicatorPath.safeResourceUrl = this.indicator.indicatorPaths[index].safeResourceUrl; this.indicator.indicatorPaths[index] = indicatorPath; } - } else { - this.urlParameterizedMessage = null; } })); } } - private isStakeholderParametersValid(indicatorPath: IndicatorPath) { - return !((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_name") == -1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") == -1) - || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") == -1 && indicatorPath.url.indexOf("index_name") == -1 && (indicatorPath.url).indexOf("index_shortName") == -1)); + public removeNumberIndicatorPath(index: number) { + this.numberIndicatorPaths.removeAt(index); + this.indicator.indicatorPaths.splice(index, 1); + this.numbersTransition.init(); + if (this.indicator.activePath === index) { + this.activeNumberIndicatorPath(Math.max(0, index - 1)); + } else if (this.indicator.activePath > index) { + this.activeNumberIndicatorPath(this.indicator.activePath - 1); + } + this.numberIndicatorFb.markAsDirty(); + } + public removeChartIndicatorPath(index: number) { + this.chartIndicatorPaths.removeAt(index); + this.indicator.indicatorPaths.splice(index, 1); + this.chartsTransition.init(); + if (this.indicator.activePath === index) { + this.activeChartIndicatorPath(Math.max(0, index - 1)); + } else if (this.indicator.activePath > index) { + this.activeChartIndicatorPath(this.indicator.activePath - 1); + } + this.chartIndicatorFb.markAsDirty(); + } + + public moveIndicatorPath(form: FormGroup, + type: 'number' | 'chart', index: number, + newIndex: number = index - 1) { + let indicatorPaths = type == 'number'?this.numberIndicatorPaths:this.chartIndicatorPaths; + if(type == 'number') { + this.numbersTransition.init(); + } else { + this.chartsTransition.init(); + } + let a = indicatorPaths.at(index); + let b = indicatorPaths.at(newIndex); + indicatorPaths.setControl(index, b); + indicatorPaths.setControl(newIndex, a); + HelperFunctions.swap(this.indicator.indicatorPaths, index, newIndex); + if (this.indicator.activePath === index) { + this.indicator.activePath = newIndex; + } else if (this.indicator.activePath === newIndex) { + this.indicator.activePath = index; + } + form.markAsDirty(); + } + + public activeNumberIndicatorPath(index: number) { + let paths = this.numberIndicatorPaths; + if (index == paths.length) { + this.addNumberIndicatorPath(); + this.numbersTransition.init(); + } + this.indicator.activePath = index; + } + + public activeChartIndicatorPath(index: number) { + let paths = this.chartIndicatorPaths; + if (index == paths.length) { + this.addChartIndicatorPath(); + this.chartsTransition.init(); + } + this.indicator.activePath = index; } private getJsonPathAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { @@ -603,6 +665,9 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple private getParametersAsFormArray(indicatorPath: IndicatorPath): UntypedFormArray { let parameters = this.fb.array([]); if (indicatorPath.parameters) { + if(!indicatorPath.parameters.statsProfile) { + indicatorPath.parameters.statsProfile = null; + } Object.keys(indicatorPath.parameters).forEach(key => { if (this.indicatorUtils.ignoredParameters.indexOf(key) === -1) { if (this.indicatorUtils.parametersValidators.has(key)) { @@ -623,7 +688,21 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple } public editNumberIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; + this.editNumberModal.cancelButtonText = 'Cancel'; + this.editNumberModal.okButtonLeft = false; + this.editNumberModal.alertMessage = false; + if (this.index === -1) { + this.editNumberModal.alertTitle = 'Create a new number indicator'; + this.editNumberModal.okButtonText = 'Save'; + this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editNumberNotify.reset(this.notification.message); + } else { + this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; + this.editNumberModal.okButtonText = 'Save Changes'; + this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editNumberNotify.reset(this.notification.message); + } + this.editNumberModal.stayOpen = true; this.section = section; this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; if (this.index !== -1) { @@ -642,7 +721,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple defaultId: this.fb.control(this.indicator.defaultId) }); this.indicator.indicatorPaths.forEach(indicatorPath => { - this.addNumberIndicatorPath(this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath), indicatorPath.format); + this.addNumberIndicatorPath(this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), this.getParametersAsFormArray(indicatorPath), indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath), indicatorPath.format); }); } else { this.indicator = new Indicator('', '', '', 'number', 'small', 'small', "PUBLIC", []); @@ -665,26 +744,26 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.numberIndicatorFb.get('description').disable(); }, 0); } - this.editNumberModal.cancelButtonText = 'Cancel'; - this.editNumberModal.okButtonLeft = false; - this.editNumberModal.alertMessage = false; - if (this.index === -1) { - this.editNumberModal.alertTitle = 'Create a new number indicator'; - this.editNumberModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } else { - this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; - this.editNumberModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editNumberNotify.reset(this.notification.message); - } - this.editNumberModal.stayOpen = true; this.editNumberModal.open(); } public editChartIndicatorOpen(section: Section, id = null) { - this.urlParameterizedMessage = null; + this.editChartModal.cancelButtonText = 'Cancel'; + this.editChartModal.okButtonLeft = false; + this.editChartModal.alertMessage = false; + if (this.index === -1) { + this.editChartModal.alertTitle = 'Create a new chart indicator'; + this.editChartModal.okButtonText = 'Save'; + this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + this.editChartNotify.reset(this.notification.message); + } else { + this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; + this.editChartModal.okButtonText = 'Save Changes'; + this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); + ; + this.editChartNotify.reset(this.notification.message); + } + this.editChartModal.stayOpen = true; this.urlSubscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); @@ -708,7 +787,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); this.indicator.indicatorPaths.forEach(indicatorPath => { this.addChartIndicatorPath(this.getUrlByStakeHolder(indicatorPath), - this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); + this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); }); } else { @@ -731,22 +810,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.chartIndicatorFb.get('description').disable(); }, 0); } - this.editChartModal.cancelButtonText = 'Cancel'; - this.editChartModal.okButtonLeft = false; - this.editChartModal.alertMessage = false; - if (this.index === -1) { - this.editChartModal.alertTitle = 'Create a new chart indicator'; - this.editChartModal.okButtonText = 'Save'; - this.notification = NotificationUtils.createIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - this.editChartNotify.reset(this.notification.message); - } else { - this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; - this.editChartModal.okButtonText = 'Save Changes'; - this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); - ; - this.editChartNotify.reset(this.notification.message); - } - this.editChartModal.stayOpen = true; this.editChartModal.open(); } @@ -754,11 +817,11 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.editing = true; if (this.indicator.type === 'chart') { this.chartIndicatorFb.get('description').enable(); - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, true); + this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type); this.section = this.charts.find(section => section._id === this.section._id); } else { this.numberIndicatorFb.get('description').enable(); - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, false); + this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type); this.section = this.numbers.find(section => section._id === this.section._id); } let path = [ @@ -846,7 +909,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.setCharts(); this.setNumbers(); this.initReorder(); - if(properties.notificationsAPIURL) { + if (properties.notificationsAPIURL) { this.notification = NotificationUtils.importIndicators(this.user.fullname, this.stakeholder.alias); this.notification.entity = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id; this.notification.name = this.user.firstname; @@ -883,20 +946,39 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple }); } } - this.editing = false; - this.importLoading = false; + this.finish(); NotificationHandler.rise('Indicators have been imported successfully!'); }, error => { this.chartIndicatorFb = null; NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); - this.editing = false; - this.importLoading = false; + this.finish(); })); } - reorderIndicators(sectionId: string, type: IndicatorType, reorder: Reorder) { + finish() { + this.editing = false; + this.loading = false; + } + + moveIndicator(moveIndicator: MoveIndicator) { + this.editing = true; + let path = [ + this.stakeholder._id, + this.stakeholder.topics[this.topicIndex]._id, + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id + ]; + this.subscriptions.push(this.stakeholderService.moveIndicator(this.properties.monitorServiceAPIURL, path, moveIndicator).subscribe(subCategory => { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex] = subCategory; + this.setCharts(); + this.setNumbers(); + this.editing = false; + })); + } + + reorderIndicators(sectionId: string, type: IndicatorType, indicators: string[]) { this.editing = true; let path = [ this.stakeholder._id, @@ -905,7 +987,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, sectionId ]; - this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, reorder, type).subscribe(indicators => { + this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, indicators).subscribe(indicators => { if (type === 'chart') { this.charts.find(section => section._id === sectionId).indicators = indicators; this.setCharts(); @@ -917,16 +999,27 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple })); } - hasDifference(index: number): boolean { + hasDifference(index: number, type: IndicatorType = 'chart'): boolean { let hasDifference = false; - this.chartIndicatorPaths.at(index).value.parameters.forEach((parameter) => { - if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { - hasDifference = true; - return; - } - }); - return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !== - this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString(); + if (type === 'chart') { + this.chartIndicatorPaths.at(index).value.parameters.forEach(parameter => { + if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { + hasDifference = true; + return; + } + }); + return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !== + this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString(); + } else if (type === 'number') { + let indicatorPath = this.numberIndicatorPaths.at(index).value; + indicatorPath.parameters.forEach(parameter => { + if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { + hasDifference = true; + return; + } + }); + } + return hasDifference; } public get isAdministrator(): boolean { @@ -937,11 +1030,18 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple return this.isAdministrator || Session.isCurator(this.stakeholder.type, this.user); } - refreshIndicator() { - this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, 'chart', true); - this.indicator.indicatorPaths.forEach(indicatorPath => { - indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); - }); + refreshIndicator(type: IndicatorType = 'chart') { + if (type === 'chart') { + this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, 'chart'); + this.indicator.indicatorPaths.forEach(indicatorPath => { + indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); + }); + } else if (type === 'number') { + this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, 'number'); + this.indicator.indicatorPaths.forEach((indicatorPath, index) => { + this.validateJsonPath(index); + }); + } } deleteIndicatorOpen(section: Section, indicatorId: string, type: string, childrenAction: string = null) { @@ -1124,24 +1224,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple })); } - // deleteNumberSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteNumberSectionModal.alertTitle = 'Delete Section'; - // this.deleteNumberSectionModal.cancelButtonText = 'No'; - // this.deleteNumberSectionModal.okButtonText = 'Yes'; - // this.deleteNumberSectionModal.open(); - // } - // - // deleteChartSectionOpen(section: Section, index: number) { - // this.section = section; - // this.index = index; - // this.deleteChartSectionModal.alertTitle = 'Delete Section'; - // this.deleteChartSectionModal.cancelButtonText = 'No'; - // this.deleteChartSectionModal.okButtonText = 'Yes'; - // this.deleteChartSectionModal.open(); - // } - deleteSectionOpen(section: Section, index: number, type: IndicatorType, childrenAction: string = null) { if (!this.editing && !section.defaultId) { this.sectionTypeToDelete = type; @@ -1198,10 +1280,6 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple })); } - private checkForSchemaEnhancements(url: string) { - this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url) && this.properties.dashboard != 'irish'; - } - migrateFromOldImportJsonFile(charts) { // first section contains numbers // second contains charts @@ -1217,35 +1295,50 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple if (chart['sectionIndex'] == null) { chart['sectionIndex'] = chart['type'] == 'chart' ? chartsSection : 0; } + if (chart.url && chart.jsonPath) { + chart.indicatorPaths = [{url: chart.url, jsonPath: chart.jsonPath}]; + } else if(chart.url) { + chart.indicatorPaths = [{url: chart.url}]; + } } return charts; } - importIndicatorsAndSave(charts: any[]) { + importIndicatorsAndSave(stakeholder: Stakeholder, charts: any[]) { let sectionsToSave: Section[] = []; let countIndicators = 0; + if (stakeholder.type !== this.stakeholder.type) { + UIkit.notification("The type of this profile is not the same with the file's one!", { + status: 'warning', + timeout: 6000, + pos: 'bottom-right' + }); + this.finish(); + return; + } // name description additionalDescription, height, width, visibility - let noValidParams = 0; let duplicates = 0; charts = this.migrateFromOldImportJsonFile(charts); for (let chart of charts) { - chart.visibility = this.showVisibility?chart.visibility:this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities); + chart.visibility = this.showVisibility ? chart.visibility : this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities); if (!sectionsToSave[chart['sectionIndex']]) { let sectionToSave = new Section(chart['sectionType'] ? chart['sectionType'] : chart['type'], chart['sectionTitle']); sectionToSave.indicators = []; sectionsToSave[chart['sectionIndex']] = sectionToSave; } let exists = false; - let indicatorPath; + let indicatorPaths: IndicatorPath[] = []; // validate indicators' schema from file let invalid_file_message; if (!chart.type) { invalid_file_message = "No indicator type is specified. Type should be chart or number."; } else if (chart.type != "chart" && chart.type != "number") { invalid_file_message = "Invalid indicator type. Type should be chart or number."; - } else if (chart.type == "number" && !chart.jsonPath) { + } else if (chart.indicatorPaths.length === 0) { + invalid_file_message = "No indicator paths are specified." + } else if (chart.type == "number" && chart.indicatorPaths.filter(path => !path.jsonPath).length > 0) { invalid_file_message = "No jsonPath is specified for number indicator." - } else if (!chart.url) { + } else if (chart.indicatorPaths.filter(path => !path.url).length > 0) { invalid_file_message = "No indicator url is specified."; } @@ -1255,46 +1348,47 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); break; } if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } + indicatorPaths = chart.indicatorPaths.map(path => this.indicatorUtils.generateIndicatorByChartUrl(this.indicatorUtils.getChartSource(path.url), path.url, chart.type, stakeholder)); + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts.forEach((section: Section) => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(path => { + let size = indicatorPaths.length; + indicatorPaths = indicatorPaths.filter(indicatorPath => JSON.stringify(path.chartObject) !== JSON.stringify(indicatorPath.chartObject)) + if (indicatorPaths.length < size) { + duplicates = duplicates + (size - indicatorPaths.length); + exists = true; + } + }); + }); + }); } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(chart.url), chart.url, this.stakeholder, - chart.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(chart.url))); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } + indicatorPaths = chart.indicatorPaths.map(path => + this.indicatorUtils.generateIndicatorByNumberUrl(this.indicatorUtils.getNumberSource(path.url), path.url, + stakeholder, path.jsonPath, this.indicatorUtils.numberSources.get(this.indicatorUtils.getNumberSource(path.url)))); + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers.forEach((section: Section) => { + section.indicators.forEach(indicator => { + indicator.indicatorPaths.forEach(path => { + let size = indicatorPaths.length; + indicatorPaths = indicatorPaths.filter(indicatorPath => JSON.stringify(path.chartObject) !== JSON.stringify(indicatorPath.chartObject)) + if (indicatorPaths.length < size) { + duplicates = duplicates + (size - indicatorPaths.length); + exists = true; + } + }); + }); + }); } - if (!this.isStakeholderParametersValid(indicatorPath)) { - noValidParams++; - } - if (!exists) { - let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility?"RESTRICTED":this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), [indicatorPath]); + if (indicatorPaths.length > 0) { + let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, this.showVisibility ? "RESTRICTED" : this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities), indicatorPaths); sectionsToSave[chart['sectionIndex']].indicators.push(i); countIndicators++; } - } - if (duplicates > 0) { UIkit.notification(duplicates + " urls already exist and will not be imported!", { status: 'warning', @@ -1302,19 +1396,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple pos: 'bottom-right' }); } - if (noValidParams > 0 && !(this.stakeholder.type == 'country')) { - let noValidMessage = "Some indicators couldn't be generated properly. Please make sure chart data is for the current stakeholder."; - if (this.stakeholder.defaultId == null) { - noValidMessage = "Some indicators couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly."; - } - UIkit.notification(noValidMessage, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - } else if (sectionsToSave.length > 0 && countIndicators > 0) { + if (sectionsToSave.length > 0 && countIndicators > 0) { this.saveIndicators(sectionsToSave.filter(section => !!section)); } if (sectionsToSave.length == 0 || countIndicators == 0) { @@ -1323,8 +1405,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); } } @@ -1335,36 +1416,41 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let indexIndicator: number = 0; this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].numbers.forEach(section => { section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, "jsonPath": indicatorPath.jsonPath, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.indicatorUtils.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); + indicators[indexIndicator] = { + "indicatorPaths": indicator.indicatorPaths.map(path => { + return { + jsonPath: path.jsonPath, + url: this.indicatorUtils.getNumberUrl(path.source, this.indicatorUtils.getFullUrl(this.stakeholder, path)) + } + }), + "type": indicator.type, "name": indicator.name, + "description": indicator.description, "additionalDescription": indicator.additionalDescription, + "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, + "sectionTitle": section.title, + "sectionType": section.type, + "sectionIndex": index + }; + indexIndicator++; }); index++; }); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].charts.forEach(section => { section.indicators.forEach(indicator => { - indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { - "type": indicator.type, "name": indicator.name, - "description": indicator.description, "additionalDescription": indicator.additionalDescription, - "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, - "url": this.getUrlByStakeHolder(indicatorPath), - "sectionTitle": section.title, - "sectionType": section.type, - "sectionIndex": index - }; - indexIndicator++; - }); + indicators[indexIndicator] = { + "indicatorPaths": indicator.indicatorPaths.map(path => { + return { + url: this.getUrlByStakeHolder(path) + } + }), + "type": indicator.type, "name": indicator.name, + "description": indicator.description, "additionalDescription": indicator.additionalDescription, + "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, + "sectionTitle": section.title, + "sectionType": section.type, + "sectionIndex": index + }; + indexIndicator++; }); index++; @@ -1373,8 +1459,12 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple let topic = this.stakeholder ? this.stakeholder.topics[this.topicIndex] : null; let category = topic ? topic.categories[this.categoryIndex] : null; let subCategory = category ? category.subCategories[subcategoryIndex] : null; - - var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(indicators)], {type: 'application/json'})); + let json = { + stakeholder: HelperFunctions.copy(this.stakeholder), + indicators: indicators + } + delete json.stakeholder.topics; + var jsonFileUrl = window.URL.createObjectURL(new Blob([JSON.stringify(json)], {type: 'application/json'})); var a = window.document.createElement('a'); window.document.body.appendChild(a); a.setAttribute('style', 'display: none'); @@ -1383,14 +1473,13 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple a.click(); window.URL.revokeObjectURL(jsonFileUrl); a.remove(); // remove the element - - this.editing = false; + this.finish(); } fileChangeEvent(fileInput: any, index) { this.index = index; this.editing = true; - this.importLoading = true; + this.loading = true; this.filesToUpload = >fileInput.target.files; this.upload(); } @@ -1403,8 +1492,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); return; } else { if (this.filesToUpload[0].name.indexOf(".json") == -1 || (this.filesToUpload[0].type != "application/json")) { @@ -1414,27 +1502,30 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); return; } } this.makeFileRequest(this.properties.utilsService + '/upload?type=json', [], this.filesToUpload).then(async (result: string) => { - - let json_result = JSON.parse(result); - + let json = JSON.parse(result); // validate file - if (!json_result || json_result.length == 0) { + if (json && Array.isArray(json)) { + UIkit.notification("This file is not supported any more. Please export indicators and try again!", { + status: 'danger', + timeout: 6000, + pos: 'bottom-right' + }); + this.finish(); + } else if (!json || json?.indicators.length == 0) { UIkit.notification("Importing file is empty", { status: 'danger', timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); } else { - this.importIndicatorsAndSave(json_result); + this.importIndicatorsAndSave(json.stakeholder, json.indicators); } }, (error) => { console.error("Error importing files", error); @@ -1443,8 +1534,7 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - this.importLoading = false; + this.finish(); }); } @@ -1482,4 +1572,8 @@ export class IndicatorsComponent extends IndicatorStakeholderBaseComponent imple document.body.removeChild(tempBox); NotificationHandler.rise('Copied to clipboard'); } + + get isEditable(): boolean { + return this.stakeholder.copy || this.stakeholder.defaultId == null || this.stakeholder.defaultId == '-1'; + } } diff --git a/monitor-admin/topic/topic.component.html b/monitor-admin/topic/topic.component.html index 46806ed5..c264fee7 100644 --- a/monitor-admin/topic/topic.component.html +++ b/monitor-admin/topic/topic.component.html @@ -28,12 +28,15 @@ - + + -
+
-
  • +
  • @@ -235,12 +240,15 @@ - + + -
    +
    - - - - - - - - - - - - @@ -369,9 +323,6 @@ export class OrcidWorkComponent { public hasConsent: boolean = false; public currentAction: string = ""; - public hoverAdd: boolean = false; - public hoverDelete: boolean = false; - public properties: EnvProperties = properties; public openaireEntities = OpenaireEntities; @@ -379,7 +330,8 @@ export class OrcidWorkComponent { private _router: Router, private orcidService: OrcidService, private resultLandingService: ResultLandingService, - private userManagementService: UserManagementService, private _logService: LogService, private _userProfileService: UserProfileService) { + private userManagementService: UserManagementService, private _logService: LogService, private _userProfileService: UserProfileService, + private cdr: ChangeDetectorRef) { if (typeof document !== 'undefined') { this.tokenUrl = properties.orcidTokenURL + "client_id=" + properties.orcidClientId @@ -391,24 +343,26 @@ export class OrcidWorkComponent { } ngOnInit() { - this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { - if (user) { - this.isLoggedIn = true; - if (!this.givenPutCode) { - this.getPutCode(); + if(this.properties.environment != 'beta') { + this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { + if (user) { + this.isLoggedIn = true; + if (!this.givenPutCode) { + this.getPutCode(); + } + } else { + this.isLoggedIn = false; } - } else { + }, error => { this.isLoggedIn = false; + })); + if (properties.dashboard == 'irish') { + this.subscriptions.push(this._userProfileService.getUserProfile().subscribe(userProfile => { + this.hasConsent = userProfile.consent; + }, error => { + this.hasConsent = false; + })); } - }, error => { - this.isLoggedIn = false; - })); - if(properties.dashboard == 'irish'){ - this.subscriptions.push(this._userProfileService.getUserProfile().subscribe(userProfile => { - this.hasConsent = userProfile.consent; - }, error =>{ - this.hasConsent = false; - })); } } @@ -491,6 +445,8 @@ export class OrcidWorkComponent { this.subscriptions.push(this.orcidService.getPutCode(this.pids).subscribe( putCodes => { this.putCodes = putCodes; + this.cdr.markForCheck(); + // this.cdr.detectChanges(); }, error => { } @@ -572,7 +528,9 @@ export class OrcidWorkComponent { this.putCodes.push("" + response['put-code']); this.creationDates.push(response['created-date']['value']); this.updateDates.push(response['last-modified-date']['value']); - + this.cdr.markForCheck(); + // this.cdr.detectChanges(); + // this.closeGrantModal(); // this.message = "You have successfully added work with pids: "+this.pids+" in your ORCID record!"; this.message = "You have successfully added work \"" + this.resultTitle + "\" in your ORCID record!"; @@ -748,6 +706,8 @@ export class OrcidWorkComponent { deletedAll = false; } else { this.putCodes.splice(i, 1); + this.cdr.markForCheck(); + // this.cdr.detectChanges(); this.creationDates.splice(i, 1); this.updateDates.splice(i, 1); // this.works.splice(i, 1); @@ -894,13 +854,18 @@ export class OrcidWorkComponent { } this.showLoading = false; } - + + get tooltipBETA() { + // return "Login to the production environment to add works to your ORCID record"; + return "Add or delete a work from your ORCID record. This feature is not available on BETA."; + } + get tooltipAdd() { - return "Add this work to your ORCID record" + ((properties.environment == "beta") ? ". The action will affect your real ORCID iD." : ""); + return (properties.environment == "beta") ? this.tooltipBETA : ("Add this work to your ORCID record" + ((properties.environment == "test") ? ". The action will affect your real ORCID iD." : "")); } get tooltipDelete() { - return "Delete this work from your ORCID record" + ((properties.environment == "beta") ? ". The action will affect your real ORCID iD." : ""); + return "Delete this work from your ORCID record" + ((properties.environment == "test") ? ". The action will affect your real ORCID iD." : ""); } get tooltipNoPid() { @@ -908,16 +873,14 @@ export class OrcidWorkComponent { } get tooltipNoLoggedInUser() { - return "Add or delete a work from your ORCID record. Please log in first." + return (properties.environment == "beta") ? this.tooltipBETA : "Add or delete a work from your ORCID record. Please log in first." } - - hoverEvent($event, action: string = "add") { - if (action == "add") { - this.hoverAdd = $event.type == "mouseover"; - this.hoverDelete = false; - } else if (action == "delete") { - this.hoverDelete = $event.type == "mouseover"; - this.hoverAdd = false; - } + + get isDisabled() { + return (this.properties.environment == 'beta' || this.showLoading || !this.isLoggedIn || (!this.pids && (!this.identifiers || this.identifiers.size == 0))); + } + + get noPids() { + return (!this.pids && (!this.identifiers || this.identifiers.size == 0)); } } diff --git a/orcid/orcid.module.ts b/orcid/orcid.module.ts index 097be324..5743c46a 100644 --- a/orcid/orcid.module.ts +++ b/orcid/orcid.module.ts @@ -1,45 +1,15 @@ import {NgModule} from '@angular/core'; -import {CommonModule} from '@angular/common'; - -import {RouterModule} from '@angular/router'; - -import {OrcidComponent} from './orcid.component'; -import {OrcidService} from './orcid.service'; -import {FreeGuard} from '../login/freeGuard.guard'; -import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; -import {OrcidWorkComponent} from './orcid-work.component'; -import {AlertModalModule} from '../utils/modal/alertModal.module'; -import {ResultLandingService} from '../landingPages/result/resultLanding.service'; -import {LoadingModule} from '../utils/loading/loading.module'; -import {ResultLandingUtilsModule} from '../landingPages/landing-utils/resultLandingUtils.module'; -import {IconsModule} from '../utils/icons/icons.module'; import {IconsService} from "../utils/icons/icons.service"; import {orcid_add, orcid_bin} from "../utils/icons/icons"; -import {FullScreenModalModule} from "../utils/modal/full-screen-modal/full-screen-modal.module"; -import {LogServiceModule} from "../utils/log/LogService.module"; +import {OrcidRoutingModule} from "./orcid-routing.module"; +import {OrcidCoreModule} from "./orcid-core.module"; +import {OrcidComponent} from "./orcid.component"; @NgModule({ - imports: [ - CommonModule, RouterModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule, - IconsModule, FullScreenModalModule, LogServiceModule - ], - declarations: [ - OrcidComponent, - OrcidWorkComponent - ], - providers:[ - FreeGuard, PreviousRouteRecorder, - OrcidService, ResultLandingService - ], - exports: [ - OrcidComponent, - OrcidWorkComponent - ] + imports: [OrcidCoreModule, OrcidRoutingModule], + exports: [OrcidComponent] }) export class OrcidModule{ - constructor(private iconsService: IconsService) { - this.iconsService.registerIcons([orcid_add, orcid_bin]) - } } diff --git a/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid-routing.module.ts b/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid-routing.module.ts new file mode 100644 index 00000000..970f5c9a --- /dev/null +++ b/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid-routing.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {LoginGuard} from "../../login/loginGuard.guard"; +import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard"; +import {SearchRecommendedResultsForOrcidComponent} from "./searchRecommendedResultsForOrcid.component"; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: SearchRecommendedResultsForOrcidComponent, + canActivate: [LoginGuard], + canDeactivate: [PreviousRouteRecorder] + } + + ]) + ] +}) +export class SearchRecommendedResultsForOrcidRoutingModule { } diff --git a/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid.module.ts b/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid.module.ts index d23ade61..b4eaa38a 100644 --- a/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid.module.ts +++ b/orcid/recommend-orcid-links/searchRecommendedResultsForOrcid.module.ts @@ -8,22 +8,23 @@ import {SearchRecommendedResultsForOrcidComponent} from './searchRecommendedResu import {SearchResultsModule } from '../../searchPages/searchUtils/searchResults.module'; import {SearchFormModule} from '../../searchPages/searchUtils/searchForm.module'; -import {IsRouteEnabled} from '../../error/isRouteEnabled.guard'; import {SearchResearchResultsModule} from "../../searchPages/searchResearchResults.module"; import {OrcidService} from "../orcid.service"; +import {SearchRecommendedResultsForOrcidRoutingModule} from "./searchRecommendedResultsForOrcid-routing.module"; // import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; @NgModule({ imports: [ CommonModule, FormsModule, RouterModule, + SearchRecommendedResultsForOrcidRoutingModule, SearchFormModule, SearchResearchResultsModule, // , BreadcrumbsModule ], declarations: [ SearchRecommendedResultsForOrcidComponent ], - providers:[ IsRouteEnabled, OrcidService], + providers:[OrcidService], exports: [ SearchRecommendedResultsForOrcidComponent ] diff --git a/reload/reload.module.ts b/reload/reload.module.ts index 788e3b5e..7574440d 100644 --- a/reload/reload.module.ts +++ b/reload/reload.module.ts @@ -6,8 +6,6 @@ import { RouterModule } from '@angular/router'; import{ReloadRoutingModule } from './reload-routing.module'; import{ReloadComponent} from './reload.component'; - -import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard'; import {LoadingModule} from "../utils/loading/loading.module"; @NgModule({ @@ -19,9 +17,7 @@ import {LoadingModule} from "../utils/loading/loading.module"; declarations: [ ReloadComponent ], - providers:[ - PreviousRouteRecorder - ], + providers:[], exports: [ ReloadComponent ] diff --git a/role-verification/role-verification.component.ts b/role-verification/role-verification.component.ts index 416c2624..07ef261d 100644 --- a/role-verification/role-verification.component.ts +++ b/role-verification/role-verification.component.ts @@ -12,6 +12,8 @@ import {EmailService} from "../utils/email/email.service"; import {Composer} from "../utils/email/composer"; import {ClearCacheService} from "../services/clear-cache.service"; import {BaseComponent} from "../sharedComponents/base/base.component"; +import {StakeholderUtils} from "../monitor-admin/utils/indicator-utils"; +import {StringUtils} from "../utils/string-utils.class"; @Component({ selector: 'role-verification', @@ -19,12 +21,9 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
    - You have been invited to join {{name}} {{(service === 'monitor' ? 'Monitor' : 'Research Community')}} Dashboard - as a manager. + You have been invited to join {{name}} {{(dashboard)}} Dashboard as a {{stakeholderUtils.roles.manager}}. Fill in the verification code, sent to - your - email, to accept the invitation request. + your email, to accept the invitation request.
    @@ -36,14 +35,12 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
    -
    + (alertOutput)="verifyMember()" [okDisabled]="(code.invalid || loading)"> +
    - You have been invited to join {{name}} Monitor Dashboard as a member. + You have been invited to join {{name}} {{(dashboard)}} Dashboard as a {{stakeholderUtils.roles.member}}. Fill in the verification code, sent - to - your - email, to accept the invitation request. + to your email, to accept the invitation request.
    @@ -54,13 +51,6 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
    -
    -
    - Welcome! You are now a member of the OpenAIRE Monitor Dashboard for the {{name}}! - From now on, you will have access to our restricted content. -
    -
    @@ -83,7 +73,7 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, public id: string; @Input() set type(type: string) { - this._type = Role.GROUP + type; + this._type = Role.GROUP + Role.mapType(type); } @Input() public name: string; @@ -93,6 +83,10 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, public userInfoLinkPrefix = ''; @Input() public userInfoLink = null; + @Input() + public relativeTo: ActivatedRoute = this._route; + @Input() + public dashboard: string = 'Research Community'; public user: User; public verification: any; public code: UntypedFormControl; @@ -103,8 +97,8 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, @ViewChild('errorModal') errorModal: AlertModal; public error: string = null; public loading: boolean = false; - public isMember: boolean = false; - + public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); + constructor(protected _route: ActivatedRoute, protected _router: Router, private fb: UntypedFormBuilder, @@ -115,18 +109,23 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, private cdr: ChangeDetectorRef) { super(); } - + ngOnInit() { this.reset(); } - + ngAfterViewInit() { + this.init(); + } + + init() { + this.ngOnDestroy(); this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.user = user; this.paramsSubscription = this._route.queryParams.subscribe(params => { if (params) { this.cdr.detectChanges(); - if(params['verify'] && !this.isMember) { + if(params['verify']) { if (this.user) { this.subscriptions.push(this.userRegistryService.getInvitation(params['verify']).subscribe(verification => { this.verification = verification; @@ -150,54 +149,46 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, 'errorCode': LoginErrorCodes.NOT_LOGIN, 'redirectUrl': this._router.url }, - relativeTo: this._route + relativeTo: this.relativeTo }); } - } else if(this.isMember) { - this.openMemberModal(); } } else { - this.isMember = false; this.cdr.detectChanges(); } }); })); } - + ngOnDestroy() { super.ngOnDestroy(); if (this.paramsSubscription instanceof Subscription) { this.paramsSubscription.unsubscribe(); } } - + public openManagerModal() { this.error = null; this.managerModal.okButtonLeft = false; this.managerModal.okButtonText = 'Accept'; this.managerModal.stayOpen = true; this.managerModal.cancelButtonText = 'Cancel'; - this.managerModal.alertTitle = 'Manager Invitation'; + this.managerModal.alertTitle = StringUtils.capitalize(this.stakeholderUtils.roles.manager) + ' Invitation'; this.managerModal.open(); } - + public openMemberModal() { this.error = null; - if(this.isMember) { - this.memberModal.cancelButton = false; - this.memberModal.okButtonText = 'Close'; - } else { - this.memberModal.cancelButton = true; - this.memberModal.okButtonText = 'Accept'; - } + this.memberModal.cancelButton = true; + this.memberModal.okButtonText = 'Accept'; this.memberModal.okButtonLeft = false; this.memberModal.stayOpen = true; this.memberModal.cancelButtonText = 'Cancel'; - this.memberModal.alertTitle = 'Member Invitation'; + this.memberModal.alertTitle = StringUtils.capitalize(this.stakeholderUtils.roles.member) + ' Invitation'; this.cdr.detectChanges(); this.memberModal.open(); } - + public openErrorModal() { this.error = null; this.errorModal.cancelButton = false; @@ -205,27 +196,20 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, this.errorModal.alertTitle = 'Invalid URL'; this.errorModal.open(); } - + public verifyManager() { this.loading = true; this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value).subscribe(() => { this.clearCacheService.clearCache('Managers updated'); this.managerModal.cancel(); this.error = null; - this.userManagementService.updateUserInfo(() => { - if (this.paramsSubscription instanceof Subscription) { - this.paramsSubscription.unsubscribe(); - } - if(this.service === "irish") { - this.loading = false; - this.userManagementService.login(properties.domain + '/admin/' + this.verification.entity); - } else if (this.service === "monitor" ) { - this.loading = false; - this._router.navigate(['/admin/' + this.verification.entity]); - } else { - this.subscriptions.push(this.emailService.notifyManagers(this.id, 'manager', + if(this.service === "irish" || this.service === "monitor") { + this.loading = false; + this.userManagementService.login(properties.domain + '/admin/' + this.verification.entity); + } else { + this.subscriptions.push(this.emailService.notifyManagers(this.id, 'manager', Composer.composeEmailToInformOldManagersForTheNewOnes(this.name, this.id)).subscribe(() => { - this.subscriptions.push(this.emailService.notifyNewManager(Composer.composeEmailForNewManager(this.id, this.name)).subscribe( + this.subscriptions.push(this.emailService.notifyNewManager(Composer.composeEmailForNewManager(this.id, this.name)).subscribe( () => { this.loading = false; window.location.href = properties.adminPortalURL + '/' + this.verification.entity; @@ -235,49 +219,38 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit, this.loading = false; window.location.href = properties.adminPortalURL + '/' + this.verification.entity; } - )); - }, error => { - console.error(error); - this.loading = false; - window.location.href = properties.adminPortalURL + '/' + this.verification.entity; - })); - } - }); + )); + }, error => { + console.error(error); + this.loading = false; + window.location.href = properties.adminPortalURL + '/' + this.verification.entity; + })); + } }, error => { this.loading = false; this.error = 'The verification code is invalid'; })); } - + public verifyMember() { this.loading = true; - if (!this.isMember) { this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value, "member").subscribe(() => { this.clearCacheService.clearCache('Members updated'); + this.memberModal.cancel(); this.loading = false; this.error = null; - this.isMember = true; - this.userManagementService.updateUserInfo(() => { - if (this.paramsSubscription instanceof Subscription) { - this.paramsSubscription.unsubscribe(); - } - this.cancel(); - }); + window.location.href = window.location.href.split('?')[0]; }, error => { this.loading = false; this.error = 'The verification code is invalid'; })); - } else { - this.memberModal.cancel(); - } } - + public reset() { this.code = this.fb.control('', [Validators.required, Validators.pattern('^[+0-9]{6}$')]); } - + cancel() { - this.isMember = false; this._router.navigate([]); } } diff --git a/sdg/sdg.component.html b/sdg/sdg.component.html index 1acb5d08..c1f431fe 100644 --- a/sdg/sdg.component.html +++ b/sdg/sdg.component.html @@ -34,9 +34,9 @@
    - + SDGs logo
    - + SDGs big logo
    @@ -61,7 +61,7 @@
    - +
    {{sdg.number == null ? '0' : sdg.number | number}} diff --git a/sdg/sdg.module.ts b/sdg/sdg.module.ts index 258d0e01..1888b381 100644 --- a/sdg/sdg.module.ts +++ b/sdg/sdg.module.ts @@ -2,14 +2,11 @@ import {CommonModule} from "@angular/common"; import {NgModule} from "@angular/core"; import {FormsModule} from "@angular/forms"; import {RouterModule} from "@angular/router"; -import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard"; import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; import {RefineFieldResultsServiceModule} from "../services/refineFieldResultsService.module"; import {LoadingModule} from "../utils/loading/loading.module"; import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module"; import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module"; -import {PiwikService} from "../utils/piwik/piwik.service"; - import {SdgRoutingModule} from './sdg-routing.module'; import {SdgComponent} from './sdg.component'; @@ -22,9 +19,7 @@ import {SdgComponent} from './sdg.component'; declarations: [ SdgComponent ], - providers: [ - PreviousRouteRecorder, PiwikService - ], + providers: [], exports: [ SdgComponent ] diff --git a/searchPages/find/searchAll.component.ts b/searchPages/find/searchAll.component.ts index 27af8480..f70ac38b 100644 --- a/searchPages/find/searchAll.component.ts +++ b/searchPages/find/searchAll.component.ts @@ -23,7 +23,8 @@ import {EnvProperties} from '../../utils/properties/env-properties'; import {SEOService} from '../../sharedComponents/SEO/SEO.service'; import {StringUtils} from '../../utils/string-utils.class'; import {SearchCustomFilter} from "../searchUtils/searchUtils.class"; -import {Subscription} from "rxjs"; +import {combineLatest, Subscription} from "rxjs"; +import {debounceTime, map} from "rxjs/operators"; import {AdvancedField, Filter} from "../searchUtils/searchHelperClasses.class"; import {SearchResearchResultsComponent} from "../searchResearchResults.component"; import {SearchProjectsComponent} from "../searchProjects.component"; @@ -219,9 +220,14 @@ export class SearchAllComponent { loadAll() { this.reloadTabs(); + // https://github.com/angular/angular/issues/26764 + this.subs.push(combineLatest([this.route.params, this.route.queryParams]) + .pipe(debounceTime(0)) + .pipe(map(results => ({params: results[0], query: results[1]}))) + .subscribe(results => { + let params = results['params']; + let queryParams = results['query']; - this.subs.push(this.route.params.subscribe(params => { - this.subs.push(this.route.queryParams.subscribe(queryParams => { this.parameters = Object.assign({}, queryParams); this.keyword = (queryParams['keyword']) ? queryParams['keyword'] : (queryParams["q"] ? queryParams["q"] : (queryParams["f0"] && queryParams["f0"] == "q" && queryParams["fv0"]?queryParams["fv0"]:"")); this.selectedFields[0].value = StringUtils.URIDecode(this.keyword); @@ -237,9 +243,8 @@ export class SearchAllComponent { active = ((["result","projects","organizations","datasources","services"]).indexOf(queryParams["active"])!= -1)?queryParams["active"]:null; delete this.parameters['active']; } - - if(this.activeEntity == null) { - if (this.activeEntity == null && (!params["entity"] || params["entity"].length == 0)) { + // if(this.activeEntity == null) { + if (this.activeEntity == null && (!params["entity"] || params["entity"].length == 0) && (!active || this.activeEntity != active)) { if (active) { this.activeEntity = active; if ((typeof document !== 'undefined')) { @@ -261,7 +266,7 @@ export class SearchAllComponent { } this.activeEntity = ((["result", "projects", "organizations", "datasources", "services"]).indexOf(entity) != -1) ? entity : this.getDefaultEntityToShow(); } - } + // } if (this.activeEntity == "result") { this.searchResults(); } else if (this.activeEntity == "projects") { @@ -274,7 +279,7 @@ export class SearchAllComponent { this.searchOrganizations(); } this.count(); - })); + // })); })); } diff --git a/searchPages/find/searchAll.module.ts b/searchPages/find/searchAll.module.ts index e35f830f..ffa0832f 100644 --- a/searchPages/find/searchAll.module.ts +++ b/searchPages/find/searchAll.module.ts @@ -12,7 +12,6 @@ import {SearchResearchResultsServiceModule} from '../../services/searchResearchR import {OrganizationsServiceModule} from '../../services/organizationsService.module'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; -import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module'; import {SearchAllComponent} from "./searchAll.component"; import {AdvancedSearchFormModule} from "../searchUtils/advancedSearchForm.module"; @@ -20,7 +19,6 @@ import {SearchResearchResultsModule} from "../searchResearchResults.module"; import {SearchProjectsModule} from "../searchProjects.module"; import {SearchOrganizationsModule} from "../searchOrganizations.module"; import {SearchDataProvidersModule} from "../searchDataProviders.module"; -import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard"; import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module"; import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module"; import {NumberRoundModule} from "../../utils/pipes/number-round.module"; @@ -31,15 +29,13 @@ import {GroupedRequestsServiceModule} from "../../services/groupedRequestsServic CommonModule, FormsModule, RouterModule, DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule, OrganizationsServiceModule, - SearchResultsModule, PiwikServiceModule, Schema2jsonldModule, SEOServiceModule, AdvancedSearchFormModule, SearchResearchResultsModule, SearchProjectsModule, SearchOrganizationsModule, SearchDataProvidersModule, BreadcrumbsModule, SliderTabsModule, NumberRoundModule, + SearchResultsModule, Schema2jsonldModule, SEOServiceModule, AdvancedSearchFormModule, SearchResearchResultsModule, SearchProjectsModule, SearchOrganizationsModule, SearchDataProvidersModule, BreadcrumbsModule, SliderTabsModule, NumberRoundModule, GroupedRequestsServiceModule ], declarations: [ SearchAllComponent ], - providers:[ - PreviousRouteRecorder - ], + providers:[], exports: [ SearchAllComponent ] diff --git a/searchPages/searchDataProviders.component.ts b/searchPages/searchDataProviders.component.ts index 0f260db2..876f7dc2 100644 --- a/searchPages/searchDataProviders.component.ts +++ b/searchPages/searchDataProviders.component.ts @@ -57,7 +57,7 @@ export class SearchDataProvidersComponent { @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { - this.customFilters = [customFilter]; + this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } @@ -370,7 +370,7 @@ export class SearchDataProvidersComponent { this.searchFiltersSub = this._searchDataProvidersService.advancedSearchDataproviders(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, this.entityType, this.properties, this.refineQuery).subscribe( res => { - let filter: Filter = res[1][0]; + let filter: Filter = res[2][0]; if(filter.values.length == 0) { filter = oldFilter; filter.countAllValues = 0; diff --git a/searchPages/searchOrganizations.component.ts b/searchPages/searchOrganizations.component.ts index 6ea539d4..45c49dcc 100644 --- a/searchPages/searchOrganizations.component.ts +++ b/searchPages/searchOrganizations.component.ts @@ -33,6 +33,7 @@ import {RefineFieldResultsService} from "../services/refineFieldResults.service" [includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter" [searchForm]="searchForm" [sort]="false" + [showRefine]="refineFields?.length > 0" [filters]="filters" [simpleView]="simpleView" formPlaceholderText="Search by organization name..." [showSwitchSearchLink]="showSwitchSearchLink" @@ -66,7 +67,7 @@ export class SearchOrganizationsComponent { @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { - this.customFilters = [customFilter]; + this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } @@ -329,7 +330,7 @@ export class SearchOrganizationsComponent { this.searchFiltersSub = this._searchOrganizationsService.advancedSearchOrganizations(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "organization", this.properties, this.refineQuery).subscribe( res => { - let filter: Filter = res[1][0]; + let filter: Filter = res[2][0]; if(filter.values.length == 0) { filter = oldFilter; filter.countAllValues = 0; diff --git a/searchPages/searchOrganizations.module.ts b/searchPages/searchOrganizations.module.ts index 664c3ab7..2e6b0056 100644 --- a/searchPages/searchOrganizations.module.ts +++ b/searchPages/searchOrganizations.module.ts @@ -1,7 +1,6 @@ import {NgModule} from '@angular/core'; import {CommonModule} from '@angular/common'; import {FormsModule} from '@angular/forms'; -import {IsRouteEnabled} from '../error/isRouteEnabled.guard'; import {NewSearchPageModule} from "./searchUtils/newSearchPage.module"; import {OrganizationsServiceModule} from "../services/organizationsService.module"; import {SearchOrganizationsComponent} from "./searchOrganizations.component"; diff --git a/searchPages/searchProjects.component.ts b/searchPages/searchProjects.component.ts index 0b394601..bb76455c 100644 --- a/searchPages/searchProjects.component.ts +++ b/searchPages/searchProjects.component.ts @@ -50,7 +50,7 @@ export class SearchProjectsComponent { @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { - this.customFilters = [customFilter]; + this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } @@ -358,7 +358,7 @@ export class SearchProjectsComponent { this.searchFiltersSub = this._searchProjectsService.advancedSearchProjects(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), 1, 0, properties, fieldsStr, [oldFilter.filterId], this.refineQuery).subscribe( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "project", this.properties, this.refineQuery).subscribe( res => { - let filter: Filter = res[1][0]; + let filter: Filter = res[2][0]; if(filter.values.length == 0) { filter = oldFilter; filter.countAllValues = 0; diff --git a/searchPages/searchResearchResults.component.ts b/searchPages/searchResearchResults.component.ts index 7b4e5f28..176ae26c 100644 --- a/searchPages/searchResearchResults.component.ts +++ b/searchPages/searchResearchResults.component.ts @@ -87,7 +87,7 @@ export class SearchResearchResultsComponent { @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { - this.customFilters = [customFilter]; + this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } diff --git a/searchPages/searchUtils/newSearchPage.component.html b/searchPages/searchUtils/newSearchPage.component.html index e52de3b5..f5349f5d 100644 --- a/searchPages/searchUtils/newSearchPage.component.html +++ b/searchPages/searchUtils/newSearchPage.component.html @@ -1,101 +1,103 @@ -

    -
    -
    -
    -
      - - -
    • - - {{customFilter.valueName}} +

      +
      +
        + + +
      • + + {{customFilter.valueName}} + +
      • +
        +
        + + + +
      • + + {{type.name}} + + +
      • +
        +
        +
        + + + +
      • + + {{filter.selectedFromAndToValues}} + + +
      • +
        +
        +
        + + + +
      • + + + + {{filter.title}}: + {{(value.name=='true'||value.name=='Yes')?'Yes':'No'}} + + + + + {{value.name | slice:0:filterPillCharactersLimit}}... + + + {{value.name}} + + -
      • + + +
        -
        - - - -
      • - - {{type.name}} - - -
      • -
        -
        -
        - - - -
      • - - {{filter.selectedFromAndToValues}} - - -
      • -
        -
        -
        - - - -
      • - - - - - {{filter.title}}: - {{(value.name=='true'||value.name=='Yes')?'Yes':'No'}} - - - - + + + + + +
      • + + + + {{filter.title}}: + {{(value.name=='true'||value.name=='Yes')?'Yes':'No'}} + + + + + {{value.name | slice:0:filterPillCharactersLimit}}... + + {{value.name}} - - - -
      • -
        -
        + + + + + +
        - - - -
      • - - - - {{filter.title}}: - {{(value.name=='true'||value.name=='Yes')?'Yes':'No'}} - - - - {{value.name}} - - - -
      • -
        -
        -
        -
      -
      - - -

    + + +

    @@ -170,10 +172,6 @@
  • - - - -
  • @@ -190,31 +188,7 @@
    - -
    -
    -
    -
    -
    -
    - - -
    -
    - - -
    -
    +
    @@ -228,7 +202,8 @@
    -
    @@ -293,9 +268,6 @@
    -
    - -
    @@ -314,9 +286,17 @@
    -
    +
    -
    + + + + + + +
    @@ -336,10 +316,10 @@ [href]="openaireLink+this.routerHelper.createQueryParamsString(this.parameterNames, this.parameterValues)" target="_blank"> OpenAIRE - Explore.
    -
    + +
    -
    +
    {{searchUtils.totalResults|number}} {{type}} @@ -359,25 +339,56 @@
    -
    +
    + *ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'" + [isDisabled]="disabled" + [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults"> - Data dump + Zenodo dumpData dump
    + +
    +
    +
    +
    + + +
    +
    +
    + +
    + + + + + Zenodo dumpData dump + + +
    +
    -
    - -
    -
    - + +
    + +
    + +
    diff --git a/searchPages/searchUtils/newSearchPage.component.ts b/searchPages/searchUtils/newSearchPage.component.ts index 01bb1acf..e8447acb 100644 --- a/searchPages/searchUtils/newSearchPage.component.ts +++ b/searchPages/searchUtils/newSearchPage.component.ts @@ -73,7 +73,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { @Input() set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { if(!Array.isArray(customFilter)) { - this.customFilters = [customFilter]; + this.customFilters = customFilter?[customFilter]:null; }else{ this.customFilters = customFilter; } @@ -131,6 +131,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { public parameterNames: string[] = []; public parameterValues: string[] = []; + filterPillCharactersLimit: number = 35; public csvLimit: number = 0; public pagingLimit: number = 0; public resultsPerPage: number = 0; @@ -234,14 +235,14 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { } private getPageContents() { - this.subscriptions.push(this.helper.getPageHelpContents(this.properties, (this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { + this.subscriptions.push(this.helper.getPageHelpContents(this.properties, (this.customFilters && this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { this.pageContents = contents; })); } private getDivContents() { - this.subscriptions.push(this.helper.getDivHelpContents(this.properties, (this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { + this.subscriptions.push(this.helper.getDivHelpContents(this.properties, (this.customFilters && this.customFilters[0] && this.customFilters[0].queryFieldName == "communityId") ? this.customFilters[0].valueId : this.properties.adminToolsCommunity, this.router.url).subscribe(contents => { this.divContents = contents; })); } @@ -1084,7 +1085,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges { let params = ""; let doisParams = ""; var DOIs: Identifier[] = Identifier.getIdentifiersFromString(value); - if ((entityType == 'publication' || entityType == 'dataset' || entityType == 'software' || entityType == 'other' || entityType == "result" || entityType == "dataprovider" || entityType == "service")) { + if ((entityType == 'publication' || entityType == 'dataset' || entityType == 'software' || entityType == 'other' || entityType == "result" || entityType == "dataprovider" || entityType == "service" || entityType == "organization")) { for (let identifier of DOIs) { // console.log(identifier) // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" diff --git a/searchPages/searchUtils/newSearchPage.module.ts b/searchPages/searchUtils/newSearchPage.module.ts index 9be5ebd5..2ec3c8b5 100644 --- a/searchPages/searchUtils/newSearchPage.module.ts +++ b/searchPages/searchUtils/newSearchPage.module.ts @@ -13,8 +13,6 @@ import {SearchPagingModule} from './searchPaging.module'; import {SearchSortingModule} from './searchSorting.module'; import {SearchDownloadModule} from './searchDownload.module'; import {ModalModule} from '../../utils/modal/modal.module'; -import {PiwikServiceModule} from '../../utils/piwik/piwikService.module'; -import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard'; import {HelperModule} from '../../utils/helper/helper.module'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module'; @@ -39,7 +37,7 @@ import {graph} from "../../utils/icons/icons"; LoadingModalModule, ReportsServiceModule, SearchPagingModule, SearchSortingModule, SearchDownloadModule, ModalModule, SearchFilterModule, RangeFilterModule, - PiwikServiceModule, HelperModule, Schema2jsonldModule, SEOServiceModule, SearchResultsModule, + HelperModule, Schema2jsonldModule, SEOServiceModule, SearchResultsModule, SearchResultsInDepositModule, SearchResultsForOrcidModule, AdvancedSearchFormModule, QuickSelectionsModule, BreadcrumbsModule, AlertModalModule, ClickModule, IconsModule, LoadingModule, InputModule @@ -47,9 +45,7 @@ import {graph} from "../../utils/icons/icons"; declarations: [ NewSearchPageComponent ], - providers: [ - PreviousRouteRecorder - ], + providers: [], exports: [ NewSearchPageComponent ] diff --git a/searchPages/searchUtils/portal-search-result.component.ts b/searchPages/searchUtils/portal-search-result.component.ts index cbf85974..7b44fbe7 100644 --- a/searchPages/searchUtils/portal-search-result.component.ts +++ b/searchPages/searchUtils/portal-search-result.component.ts @@ -60,7 +60,7 @@ export class PortalSearchResultComponent implements OnInit{ hasPermission(result: CommunityInfo & StakeholderInfo) { if(this.type === "community") { - return result.status === "all" || (result.status === "manager" && result.isManager); + return result.isPublic() || (result.isRestricted() && result.isManager); } else if(this.type === "stakeholder") { return result.visibility === "PUBLIC" || (result.visibility === "RESTRICTED" && (result.isManager || result.isMember)) || (result.visibility === "PRIVATE" && result.isManager); diff --git a/searchPages/searchUtils/searchDownload.component.ts b/searchPages/searchUtils/searchDownload.component.ts index 39448aec..2a506fb1 100644 --- a/searchPages/searchUtils/searchDownload.component.ts +++ b/searchPages/searchUtils/searchDownload.component.ts @@ -15,12 +15,11 @@ import {properties} from "../../../../environments/environment"; selector: 'search-download', template: ` diff --git a/searchPages/searchUtils/searchResult.component.ts b/searchPages/searchUtils/searchResult.component.ts index 4303238b..d76c1de6 100644 --- a/searchPages/searchUtils/searchResult.component.ts +++ b/searchPages/searchUtils/searchResult.component.ts @@ -57,7 +57,7 @@ export class SearchResultComponent implements OnInit, OnChanges { this.previewResults.push(this.getResultPreview(result)); } - if ((properties.adminToolsPortalType == "explore" || properties.adminToolsPortalType == "community" || properties.adminToolsPortalType == "aggregator") + if ((properties.adminToolsPortalType == "explore" || properties.adminToolsPortalType == "community" || properties.adminToolsPortalType == "aggregator" || properties.dashboard == "irish") && Session.isLoggedIn() && this.results && this.results.length > 0 && (this.type == "result" || this.type == "publication" || this.type == "dataset" || this.type == "software" || this.type == "other") ) { @@ -78,6 +78,7 @@ export class SearchResultComponent implements OnInit, OnChanges { // console.debug(i, this.previewResults[i].orcidPutCodes); } } + // this.previewResults = JSON.parse(JSON.stringify(this.previewResults, this.replacer), this.reviver); }, error => { } @@ -85,6 +86,26 @@ export class SearchResultComponent implements OnInit, OnChanges { } } + private replacer(key, value) { + if(value instanceof Map) { + return { + dataType: 'Map', + value: Array.from(value.entries()), // or with spread: value: [...value] + }; + } else { + return value; + } + } + + private reviver(key, value) { + if(typeof value === 'object' && value !== null) { + if (value.dataType === 'Map') { + return new Map(value.value); + } + } + return value; + } + public getResultPreview(result: SearchResult): ResultPreview { return ResultPreview.searchResultConvert(result, (result.entityType) ? result.entityType : this.type); } diff --git a/searchPages/searchUtils/searchSorting.component.ts b/searchPages/searchUtils/searchSorting.component.ts index 88afac19..92a50b1d 100644 --- a/searchPages/searchUtils/searchSorting.component.ts +++ b/searchPages/searchUtils/searchSorting.component.ts @@ -7,7 +7,7 @@ import {properties} from "../../../../environments/environment"; template: `
    diff --git a/services/organization.service.ts b/services/organization.service.ts index 722d1338..b74bd92f 100644 --- a/services/organization.service.ts +++ b/services/organization.service.ts @@ -8,9 +8,11 @@ import {OrganizationInfo} from '../utils/entities/organizationInfo'; import{EnvProperties} from '../utils/properties/env-properties'; import {map} from "rxjs/operators"; import {ParsingFunctions} from "../landingPages/landing-utils/parsingFunctions.class"; +import {properties} from "../../../environments/environment"; @Injectable() export class OrganizationService { + public parsingFunctions: ParsingFunctions = new ParsingFunctions(); constructor(private http: HttpClient ) {} @@ -92,6 +94,10 @@ export class OrganizationService { } } } + + if(organization['pid'] && properties.environment != "production") { + this.organizationInfo.identifiers = this.parsingFunctions.parseIdentifiers(organization['pid']); + } } //Comment Parsing Projects info diff --git a/services/searchOrganizations.service.ts b/services/searchOrganizations.service.ts index 488b0e87..019b8146 100644 --- a/services/searchOrganizations.service.ts +++ b/services/searchOrganizations.service.ts @@ -9,9 +9,11 @@ import{EnvProperties} from '../utils/properties/env-properties'; import {StringUtils} from '../utils/string-utils.class'; import {map} from "rxjs/operators"; import {ParsingFunctions} from "../landingPages/landing-utils/parsingFunctions.class"; +import {properties} from "../../../environments/environment"; @Injectable() export class SearchOrganizationsService { + public parsingFunctions: ParsingFunctions = new ParsingFunctions(); constructor(private http: HttpClient ) {} @@ -173,7 +175,11 @@ export class SearchOrganizationsService { result.country = resData.country.classname; } - results.push(result); + if(resData['pid'] && properties.environment != "production") { + result.identifiers = this.parsingFunctions.parseIdentifiers(resData['pid']); + } + + results.push(result); } return results; diff --git a/services/searchProjects.service.ts b/services/searchProjects.service.ts index e9c48eaa..e9e704b9 100644 --- a/services/searchProjects.service.ts +++ b/services/searchProjects.service.ts @@ -231,6 +231,7 @@ export class SearchProjectsService { let fundingData = Array.isArray(resData['fundingtree']) ? resData['fundingtree'][z] : resData['fundingtree']; if(fundingData.hasOwnProperty("funder")) { result['funderShortname'] = fundingData['funder'].shortname; + result['funderName'] = fundingData['funder'].name; result['funderId'] = fundingData['funder'].id; result['jurisdiction'] = (fundingData['funder']['id']['jurisdiction'] )?fundingData['funder']['id']['jurisdiction']:""; diff --git a/services/searchResearchResults.service.ts b/services/searchResearchResults.service.ts index 3e49a7cc..aadcd730 100644 --- a/services/searchResearchResults.service.ts +++ b/services/searchResearchResults.service.ts @@ -133,7 +133,14 @@ export class SearchResearchResultsService { return this.http.get((properties.useLongCache && size == 0 && !params && (!refineQuery || !refineQuery.includes("fq="))) ? (properties.cacheUrl + encodeURIComponent(url)) : url) .pipe(map(res => [res['meta'].total, this.parseResults(resultType, res['results'], properties), RefineResultsUtils.parse(res['refineResults'], refineFields, "publication")])); } + countResults(field:string,value:string): any { + let url = properties.utilsService + "/portals/countResults"; + if (field && value) { + url += "?field=" + encodeURIComponent(field) + "&value="+encodeURIComponent(value); + } + return this.http.get((properties.useLongCache ) ? (properties.cacheUrl + encodeURIComponent(url)) : url); + } searchResultForEntity(resultType: string, params: string, page: number, size: number, properties: EnvProperties): any { let link = properties.searchAPIURLLAst; //let url = link+params+"/"+this.getEntityQueryName(resultType,true)+ "?format=json"; diff --git a/services/servicesUtils/refineResults.class.ts b/services/servicesUtils/refineResults.class.ts index dcd48d17..dd802f32 100644 --- a/services/servicesUtils/refineResults.class.ts +++ b/services/servicesUtils/refineResults.class.ts @@ -70,7 +70,7 @@ export class RefineResultsUtils { } public static inParenthesisThePartAfterCharacters(field, characters):string { if( field.name.indexOf(characters) !=-1){ - return field.name.split(characters)[0]+" ("+field.name.split(characters)[1]+")"; + return field.name.split(characters)[0]+ (field.name.split(characters)[1]?(" ("+field.name.split(characters)[1]+")"):""); } return field.name; diff --git a/services/user-management.service.ts b/services/user-management.service.ts index 5a19d43b..08f4c0ff 100644 --- a/services/user-management.service.ts +++ b/services/user-management.service.ts @@ -35,7 +35,11 @@ export class UserManagementService { this.routerSubscription.unsubscribe(); } } - + + public static userInfoUrl(index = 0): string { + return (isArray(properties.loginServiceURL)?properties.loginServiceURL[index]:properties.loginServiceURL) + UserManagementService.USERINFO; + } + public get user(): User { return this.getUserInfoSubject.getValue(); } @@ -45,8 +49,7 @@ export class UserManagementService { } public getUserInfoAt(index = 0): Observable { - return this.http.get((isArray(properties.loginServiceURL)?properties.loginServiceURL[index]:properties.loginServiceURL) + - UserManagementService.USERINFO, CustomOptions.registryOptions()).pipe(map(userInfo => { + return this.http.get(UserManagementService.userInfoUrl(index), CustomOptions.registryOptions()).pipe(map(userInfo => { return new User(userInfo); })) } diff --git a/sharedComponents/bottom.component.html b/sharedComponents/bottom.component.html index c978bf51..dd70125f 100644 --- a/sharedComponents/bottom.component.html +++ b/sharedComponents/bottom.component.html @@ -1,5 +1,5 @@ -
    +
    flag black white low
    @@ -64,7 +64,7 @@ height="50px" class="el-image" alt="OpenAIRE" loading="lazy">
    -
    +
    @@ -101,7 +101,7 @@
  • Monitor
  • -
  • Develop
  • +
  • Develop
  • @@ -208,7 +208,7 @@ height="50px" class="el-image" alt="OpenAIRE" loading="lazy">
    -
    +
    diff --git a/sharedComponents/input/input.component.ts b/sharedComponents/input/input.component.ts index 35a0f12d..83f7114a 100644 --- a/sharedComponents/input/input.component.ts +++ b/sharedComponents/input/input.component.ts @@ -336,7 +336,12 @@ export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChang @Input() set options(options: (Option | string | number) []) { this.optionsArray = options.map(option => { - if (typeof option === 'string' || typeof option === 'number') { + if(option === null) { + return { + label: this.noValueSelected, + value: '' + }; + } else if (typeof option === 'string' || typeof option === 'number') { return { label: option.toString(), value: option diff --git a/sharedComponents/menu.ts b/sharedComponents/menu.ts index e3b38e60..b4328834 100644 --- a/sharedComponents/menu.ts +++ b/sharedComponents/menu.ts @@ -23,10 +23,11 @@ export class MenuItem { isFeatured: boolean; isActive: boolean; target: string = "_blank"; + badge?: string = ""; // used only for RDGraph portal (FAIRCORE4EOSC) constructor(id: string, title: string, url: string, route: string, needsAuthorization: boolean, entitiesRequired: string[], routeRequired: string[], params, icon: Icon = null, fragment = null, customClass = null, routeActive = null, - target: string = "_blank", type: string = "internal", isFeatured: boolean = false, items: MenuItem[] = []) { + target: string = "_blank", type: string = "internal", isFeatured: boolean = false, items: MenuItem[] = [], badge: string = "") { this._id = id; this.title = title; this.url = url; @@ -43,6 +44,7 @@ export class MenuItem { this.target = target; this.type = type; this.isFeatured = isFeatured; + this.badge = badge; } public static isTheActiveMenu(menu: MenuItem, currentRoute: any, activeMenuItem: string = ""): boolean { diff --git a/sharedComponents/navigationBar.component.html b/sharedComponents/navigationBar.component.html index 7f502eab..a0147369 100644 --- a/sharedComponents/navigationBar.component.html +++ b/sharedComponents/navigationBar.component.html @@ -41,7 +41,9 @@ {{menu.title}} + [fragment]="menu.fragment"> + {{menu.badge}} + {{menu.title}} {{menu.title}} - {{menu.title}} + + {{menu.badge}} + {{menu.title}}
    diff --git a/sharedComponents/quick-contact/quick-contact.component.html b/sharedComponents/quick-contact/quick-contact.component.html index 116060f7..23e3d1ab 100644 --- a/sharedComponents/quick-contact/quick-contact.component.html +++ b/sharedComponents/quick-contact/quick-contact.component.html @@ -1,18 +1,18 @@
    -
    -
    +
    Send a message
    - + contact person
    How can we help? diff --git a/sharedComponents/quick-contact/quick-contact.component.ts b/sharedComponents/quick-contact/quick-contact.component.ts index bf8f75e9..ccf17492 100644 --- a/sharedComponents/quick-contact/quick-contact.component.ts +++ b/sharedComponents/quick-contact/quick-contact.component.ts @@ -11,6 +11,7 @@ declare var UIkit; styleUrls: ['quick-contact.component.less'] }) export class QuickContactComponent implements OnInit, OnDestroy { + public quickContactClicked: boolean = false; public showDrop: boolean = false; @Input() public contactForm: FormGroup; diff --git a/sharedComponents/tabs/slider-tabs.component.ts b/sharedComponents/tabs/slider-tabs.component.ts index d4246f23..666f90a2 100644 --- a/sharedComponents/tabs/slider-tabs.component.ts +++ b/sharedComponents/tabs/slider-tabs.component.ts @@ -6,11 +6,14 @@ import { ElementRef, EventEmitter, Input, OnDestroy, Output, QueryList, - ViewChild + ViewChild, + Inject, + PLATFORM_ID } from "@angular/core"; import {SliderTabComponent} from "./slider-tab.component"; import {ActivatedRoute, Router} from "@angular/router"; import {Subscription} from "rxjs"; +import {isPlatformServer} from "@angular/common"; import Timeout = NodeJS.Timeout; declare var UIkit; @@ -20,7 +23,7 @@ declare var UIkit; template: `
    -
    +
    - - + + + +
    `, }) @@ -112,6 +117,11 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { * */ @Input() public flexPosition: 'center' | 'left' | 'right' = 'left'; + /** + * Set a class for the container + * */ + @Input() + public containerClass: string; /** * Set a class above tabs * */ @@ -138,10 +148,13 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { private subscriptions: any[] = []; private observer: IntersectionObserver; private timeout: Timeout; + isServer: boolean; constructor(private route: ActivatedRoute, private router: Router, - private cdr: ChangeDetectorRef) { + private cdr: ChangeDetectorRef, + @Inject(PLATFORM_ID) private platform: any) { + this.isServer = isPlatformServer(this.platform); } ngAfterViewInit() { @@ -164,7 +177,7 @@ export class SliderTabsComponent implements AfterViewInit, OnDestroy { } }); if (this.type === 'static') { - let tabs = UIkit.tab(this.tabsElement.nativeElement, {connect: this.connect}); + let tabs = UIkit.switcher(this.tabsElement.nativeElement, {connect: this.connect}); tabs.show(this.activeIndex); if (this.connect.includes('#')) { this.scrollToStart(); diff --git a/timeout-interceptor.service.ts b/timeout-interceptor.service.ts index 224e585e..3b5c2fff 100644 --- a/timeout-interceptor.service.ts +++ b/timeout-interceptor.service.ts @@ -13,7 +13,7 @@ export class TimeoutInterceptor implements HttpInterceptor { private static TIMEOUT_WHITELIST = [ properties.csvAPIURL, properties.registryUrl, properties.claimsAPIURL, properties.searchCrossrefAPIURL, properties.searchDataciteAPIURL, - properties.statisticsAPIURL, properties.searchAPIURLLAst, properties.monitorStatsFrameUrl]; + properties.statisticsAPIURL, properties.monitorStatsFrameUrl]; constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number, @Inject(PLATFORM_ID) private platformId: any) { } diff --git a/utils/authors/showAuthors.component.ts b/utils/authors/showAuthors.component.ts index 837bbbbf..a400b722 100644 --- a/utils/authors/showAuthors.component.ts +++ b/utils/authors/showAuthors.component.ts @@ -1,4 +1,13 @@ -import {Component, Inject, Input, PLATFORM_ID, ViewChild} from '@angular/core'; +import { + AfterContentInit, + AfterViewInit, + ChangeDetectorRef, + Component, + Inject, + Input, + PLATFORM_ID, + ViewChild +} from '@angular/core'; import {ActivatedRoute} from "@angular/router"; import {RouterHelper} from "../routerHelper.class"; import {EnvProperties} from '../properties/env-properties'; @@ -10,90 +19,90 @@ import {properties} from "../../../../environments/environment"; @Component({ selector: 'showAuthors', template: ` - - - {{author.fullName + ";"}} - - - - orcid - orcid bw - - {{author.fullName + ";"}} - - -
    - -
    - -
    - -
    -
    - -
    -
    {{author.fullName}}
    -
    -
    ORCID
    - -
    - {{" "}} - {{" "}} - - Harvested from ORCID Public Data File - Derived by OpenAIRE algorithms or harvested - from 3d party repositories -
    -
    -
    - - -
    - -
    -
    - -
    -
    - {{author.fullName}} in OpenAIRE -
    - -
    -
    -
    - + + + {{author.fullName + ";"}} + + + + orcid + orcid bw + + {{author.fullName + ";"}} + + +
    + +
    + +
    + +
    +
    + +
    +
    {{author.fullName}}
    +
    +
    ORCID
    + +
    + {{" "}} + {{" "}} + + Harvested from ORCID Public Data File + Derived by OpenAIRE algorithms or harvested + from 3d party repositories +
    +
    +
    + + +
    + +
    +
    + +
    +
    + {{author.fullName}} in OpenAIRE +
    + +
    +
    +
    + *ngTemplateOutlet="author_template; context: { author: author, i:i, italic: true, modal: modal}"> +{{authors.length - authorsLimit | number}} more @@ -118,18 +127,18 @@ import {properties} from "../../../../environments/environment";
    - +
    - +
    - +
    - +
    @@ -160,11 +169,14 @@ export class ShowAuthorsComponent { } ngOnInit() {} - + public onClick() { if (this.modal) { this.modal.cancel(); } + if(this.authorsModal) { + this.authorsModal.cancel(); + } } public viewAllClick() { diff --git a/utils/email/composer.ts b/utils/email/composer.ts index 676dc4c2..ab3c69f0 100644 --- a/utils/email/composer.ts +++ b/utils/email/composer.ts @@ -2,6 +2,7 @@ import {Email} from "./email"; import {Body} from "./body"; import {properties} from "../../../../environments/environment"; import {User} from "../../login/utils/helper.class"; +import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils"; export class Composer { private static noteBodySize = "14px"; @@ -335,13 +336,13 @@ export class Composer { email.subject = 'National Open Access Monitor Ireland | ' + name; email.recipient = recipient; email.body = '

    Dear user,

    ' + - '

    You have been invited to be a ' + role +' of the for the National Open Access Monitor, Ireland dashboard for the ' + name + '.

    ' + + '

    You have been invited to be a ' + StakeholderConfiguration.ROLES[role] +' of the for the National Open Access Monitor, Ireland dashboard for the ' + name + '.

    ' + '

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

    ' + '

    The verification code is ((__code__)).

    ' + '

    At your first sign in you will be asked to accept and consent to the "OpenAIRE Personal Data Protection Policy and Consent Form" to be able to use the service.

    ' + (role === "manager"? - '

    As a manager of the National Open Access Monitor, Ireland, you will have access to the administration part of the dashboard, where you will be able to also invite other users to become managers.

    ': - '

    As a member of the OpenAIRE Monitor Dashboard, you will have access to the restricted access areas of the profile for the ' + name + '.') + + '

    As a ' + StakeholderConfiguration.ROLES[role] + ' of the National Open Access Monitor, Ireland, you will have access to the administration part of the dashboard, where you will be able to also invite other users to become ' + StakeholderConfiguration.ROLES['member'] + 's.

    ': + '

    As a ' + StakeholderConfiguration.ROLES[role] + ' of the National Open Access Monitor, Ireland, you will have access to the sandbox of the profile for the ' + name + '.') + '

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

    ' + '

    Kind Regards
    The OpenAIRE Team

    ' + diff --git a/utils/entities/organizationInfo.ts b/utils/entities/organizationInfo.ts index 6bd9b68f..5194f076 100644 --- a/utils/entities/organizationInfo.ts +++ b/utils/entities/organizationInfo.ts @@ -26,4 +26,5 @@ export class OrganizationInfo { // organizations: {name: string; url: string}[]}[]; deletedByInferenceIds: string[]; + identifiers: Map; //key is the classname } diff --git a/utils/entities/searchResult.ts b/utils/entities/searchResult.ts index e59e56f7..ba762833 100644 --- a/utils/entities/searchResult.ts +++ b/utils/entities/searchResult.ts @@ -48,6 +48,7 @@ export class SearchResult { acronym: string; code: string; // callIdentifier?: string; // currently not parsed + funderName: string; funderShortname: string; budget?: string; contribution?: string; diff --git a/utils/entitiesAutoComplete/entitySearch.service.ts b/utils/entitiesAutoComplete/entitySearch.service.ts index f7cc9478..5580445f 100644 --- a/utils/entitiesAutoComplete/entitySearch.service.ts +++ b/utils/entitiesAutoComplete/entitySearch.service.ts @@ -237,7 +237,8 @@ private fetch (link,id,oafEntityType,type, properties:EnvProperties ){ if(resData['fundingtree'] && resData['fundingtree']['funder']){ value.funderId = (resData['fundingtree']['funder']['id'] )?resData['fundingtree']['funder']['id']:""; - value.funderName = (resData['fundingtree']['funder']['shortname'] )?resData['fundingtree']['funder']['shortname']:""; + value.funderName = (resData['fundingtree']['funder']['name'] )?resData['fundingtree']['funder']['name']:""; + value.funderShortName = (resData['fundingtree']['funder']['shortname'] )?resData['fundingtree']['funder']['shortname']:""; value.jurisdiction = (resData['fundingtree']['funder']['jurisdiction'] )?resData['fundingtree']['funder']['jurisdiction']:""; if(resData['fundingtree']['funding_level_2']){ value.fundingLevel0 = (resData['fundingtree']['funding_level_2'] && resData['fundingtree']['funding_level_2']['parent'] && diff --git a/utils/entity-actions/entity-actions.component.ts b/utils/entity-actions/entity-actions.component.ts index f2e07c77..bf2c628a 100644 --- a/utils/entity-actions/entity-actions.component.ts +++ b/utils/entity-actions/entity-actions.component.ts @@ -14,8 +14,7 @@ import {EnvProperties} from "../properties/env-properties";
    Embed @@ -99,6 +95,7 @@ export class EntityActionsComponent implements OnInit { @Input() embed: boolean = false; @Input() url: string; @Input() isMobile: boolean = false; + @Input() showTooltip: boolean = true; public citeThisClicked: boolean; public routerHelper: RouterHelper = new RouterHelper(); @ViewChild('citeModal') citeModal; diff --git a/utils/mobile-dropdown/mobile-dropdown.component.ts b/utils/mobile-dropdown/mobile-dropdown.component.ts index f1b3c2ef..db944564 100644 --- a/utils/mobile-dropdown/mobile-dropdown.component.ts +++ b/utils/mobile-dropdown/mobile-dropdown.component.ts @@ -1,4 +1,4 @@ -import {Component, ElementRef, EventEmitter, Input, OnInit, Output} from "@angular/core"; +import {ChangeDetectorRef, Component, ElementRef, EventEmitter, Input, OnInit, Output} from "@angular/core"; import {NavigationStart, Router} from "@angular/router"; @Component({ @@ -21,7 +21,7 @@ export class MobileDropdownComponent implements OnInit{ public opened: boolean = false; private static MOBILE_DROPDOWN_CONTAINER = 'mobile-dropdown-container'; - constructor(private element: ElementRef, private router: Router) { + constructor(private element: ElementRef, private router: Router, private cdr: ChangeDetectorRef) { this.router.events.subscribe(event => { if(event instanceof NavigationStart) { this.element.nativeElement.remove(); @@ -56,6 +56,7 @@ export class MobileDropdownComponent implements OnInit{ parent.removeChild(this.element.nativeElement); container.append(this.element.nativeElement); this.opened = true; + this.cdr.markForCheck(); body.setAttribute('style', 'overflow-y: hidden'); } } @@ -63,6 +64,7 @@ export class MobileDropdownComponent implements OnInit{ close() { if(this.opened) { this.opened = false; + this.cdr.detectChanges(); this.onClose.emit(); document.getElementsByTagName('body')[0].setAttribute('style', ''); } diff --git a/utils/piwik/previousRouteRecorder.guard.ts b/utils/piwik/previousRouteRecorder.guard.ts index 4d050618..31959034 100644 --- a/utils/piwik/previousRouteRecorder.guard.ts +++ b/utils/piwik/previousRouteRecorder.guard.ts @@ -6,7 +6,7 @@ import {properties} from "../../../../environments/environment"; @Injectable({ providedIn: 'root' -}) // do not forget to register this class as a provider +}) export class PreviousRouteRecorder { constructor(private router: Router) { } diff --git a/utils/properties/env-properties.ts b/utils/properties/env-properties.ts index b6e3b370..f740381d 100644 --- a/utils/properties/env-properties.ts +++ b/utils/properties/env-properties.ts @@ -45,6 +45,10 @@ export interface EnvProperties { openDoarURL?: string; r3DataURL?: string; swhURL?: string; + rorURL?: string; + isniURL?: string; + wikiDataURL?: string; + fundRefURL?: string; fairSharingURL?: string, eoscMarketplaceURL?: string, sherpaURL?: string; diff --git a/utils/properties/environments/environment.ts b/utils/properties/environments/environment.ts index f462caeb..283a1295 100644 --- a/utils/properties/environments/environment.ts +++ b/utils/properties/environments/environment.ts @@ -6,7 +6,7 @@ export let common: EnvProperties = { useNewStatistisTool: true, openCitationsAPIURL: "https://services.openaire.eu/opencitations/getCitations?id=", searchCrossrefAPIURL: "https://api.crossref.org/works", - searchDataciteAPIURL: "https://api.datacite.org/works", + searchDataciteAPIURL: "https://api.datacite.org/dois", searchOrcidURL: "https://pub.orcid.org/v2.1/", orcidURL: "https://orcid.org/", orcidAPIURL: "https://services.openaire.eu/uoa-orcid-service/", @@ -20,6 +20,10 @@ export let common: EnvProperties = { openDoarURL: "http://v2.sherpa.ac.uk/id/repository/", r3DataURL: "http://service.re3data.org/repository/", swhURL: "https://archive.softwareheritage.org/", + rorURL: "https://ror.org/", + isniURL: "https://isni.org/isni/", + wikiDataURL: "https://www.wikidata.org/wiki/", + fundRefURL: "https://data.crossref.org/fundingdata/funder/", fairSharingURL: "https://fairsharing.org/", eoscMarketplaceURL: "https://marketplace.eosc-portal.eu/services/", sherpaURL: "http://sherpa.ac.uk/romeo/issn/", @@ -77,7 +81,7 @@ export let common: EnvProperties = { b2noteAPIURL: 'https://b2note.eudat.eu/', myOrcidLinksPage: "/my-orcid-links", - footerGrantText: "OpenAIRE has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreements No. 777541 and 101017452", + footerGrantText: "OpenAIRE has received funding from a series of EU funded projects.", //connect enermapsURL: "https://lab.idiap.ch/enermaps", @@ -86,6 +90,9 @@ export let common: EnvProperties = { afterLoginRedirectLink: '/myCommunities', searchLinkToCommunities: '/search/find/communities', openOrgsUrl:"https://beta.orgs.openaire.eu", + + // monitor + searchLinkToStakeholders: "/browse" } export let commonDev: EnvProperties = { diff --git a/utils/properties/searchFields.base.ts b/utils/properties/searchFields.base.ts index 79ece5b3..a029a42e 100644 --- a/utils/properties/searchFields.base.ts +++ b/utils/properties/searchFields.base.ts @@ -333,6 +333,14 @@ export class SearchFieldsBase { operator: "pf", equalityOperator: " = ", filterType: "triplet" + }, + ["haslicense"]: { + name: "License", + type: "triplet", + param: "haslicense", + operator: "hl", + equalityOperator: " = ", + filterType: "triplet" } }; @@ -369,6 +377,11 @@ export class SearchFieldsBase { { name: "All", id: "", count: "0" }, { name: "Yes", id: "true", count: "0" }, { name: "No", id: "false", count: "0" } + ], + ["haslicense"]: [ + { name: "All", id: "", count: "0" }, + { name: "Yes", id: "true", count: "0" }, + { name: "No", id: "false", count: "0" } ] }; @@ -784,8 +797,8 @@ export class SearchFieldsBase { //ORGANIZATION - public ORGANIZATION_REFINE_FIELDS: string[] = ["country"] - public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "country"]; + public ORGANIZATION_REFINE_FIELDS: string[] = ["countrynojurisdiction"] + public ORGANIZATION_ADVANCED_FIELDS: string[] = ["q", "organizationlegalname", "organizationlegalshortname", "countrynojurisdiction", "pid"]; public ORGANIZATION_FIELDS: { [key: string]: FieldDetails } = { ["q"]: {name: "Any field", type: "keyword", param: "q", operator: "op", equalityOperator: "=", filterType: null}, @@ -805,7 +818,7 @@ export class SearchFieldsBase { equalityOperator: "=", filterType: null }, - ["country"]: { + ["countrynojurisdiction"]: { name: "Country", type: "vocabulary", param: "country", @@ -813,6 +826,7 @@ export class SearchFieldsBase { equalityOperator: " exact ", filterType: "checkbox" }, + ["pid"]: {name: "PID", type: "keyword", param: "pid", operator: "pd", equalityOperator: " exact ", filterType: null} }; // public ORGANIZATION_INDEX:string[] = ["organizationcountryname"]//,"organizationeclegalbody"]; // public ADVANCED_SEARCH_ORGANIZATION_PARAM:string[] = ["q","contenttype","compatibility","country","type"]; @@ -948,7 +962,7 @@ export class SearchFieldsBase { return "and"; } else if (fieldId == "instancetypename" || fieldId == "eoscdatasourcetype" || fieldId == "resultlanguagename" || fieldId == "datasourceodlanguages" - || fieldId == "datasourcecompatibilityname" || fieldId == "country" || fieldId == "datasourceodcontenttypes" + || fieldId == "datasourcecompatibilityname" || fieldId == "country" || fieldId == "countrynojurisdiction" || fieldId == "datasourceodcontenttypes" || fieldId == "resulthostingdatasource" || fieldId == "collectedfrom") { return "or"; } diff --git a/utils/rangeFilter/rangeFilter.component.ts b/utils/rangeFilter/rangeFilter.component.ts index dcf0d9a3..3c7e5e48 100644 --- a/utils/rangeFilter/rangeFilter.component.ts +++ b/utils/rangeFilter/rangeFilter.component.ts @@ -21,7 +21,7 @@ export class RangeFilterComponent { @Input() yearMax: number = Dates.yearMax; @Input() mandatoryRange:boolean = false; public currentYear: number = Dates.currentYear; - public yearValidators = [StringUtils.inValidYearValidator(this.yearMin, this.yearMax)]; + public yearValidators; public formValidators = [StringUtils.fromYearAfterToYearValidator]; public rangeForm: UntypedFormGroup; public yearRange: YearRange = { @@ -41,6 +41,11 @@ export class RangeFilterComponent { constructor(private _router: Router, private route: ActivatedRoute, private _fb: UntypedFormBuilder) {} ngOnInit() { + this.yearValidators = [StringUtils.inValidYearValidator(this.yearMin, this.yearMax)]; + this.yearRange = { + from: {control: 'yearFrom', placeholder: this.yearMin.toString()}, + to: {control: 'yearTo', placeholder: this.yearMax.toString()} + } if(this.mandatoryRange) { this.formValidators.push(StringUtils.rangeRequired(this.mandatoryRange)); } diff --git a/utils/result-preview/result-preview.component.html b/utils/result-preview/result-preview.component.html index 96832b0a..70fa4f30 100644 --- a/utils/result-preview/result-preview.component.html +++ b/utils/result-preview/result-preview.component.html @@ -95,12 +95,12 @@
    -
    - +
    + Funder: - {{result.funderShortname}} + {{result.funderName ? result.funderName : result.funderShortname}} - + {{openaireEntities.PROJECT}} Code: {{result.code}} @@ -187,7 +187,8 @@ [deposit]="deposit" [embed]="embed" [type]="result.resultType" [result]="result" [id]="result.objId?result.objId:result.id" - [url]="properties.domain + properties.baseLink + url + '?' + urlParam + '=' + result.id"> + [url]="properties.domain + properties.baseLink + url + '?' + urlParam + '=' + result.id" + [showTooltip]="false"> Access Routes -
    +
    @@ -263,7 +264,7 @@ {{formatNumber(result.measure.bip[0].value)}}{{result.measure.bip[0].value}} -
    +
    @@ -289,7 +290,7 @@ [name]="result.measure.counts[0].icon">{{formatNumber(result.measure.counts[0].value)}} -
    +
    @@ -331,7 +332,8 @@ [type]="result.resultType" [result]="result" [id]="result.objId?result.objId:result.id" [url]="properties.domain + properties.baseLink + url + '?' + urlParam + '=' + result.id" - [isMobile]="isMobile"> + [isMobile]="isMobile" + [showTooltip]="false"> ): Identifier { - let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data", "swhid"]; - if(identifiers) { + let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data", "swhid", "ror", "wikidata", "fundref", "isni"]; + if(identifiers && identifiers.size > 0) { for (let cl of classes) { if (identifiers.get(cl)) { for (let pid of identifiers.get(cl)) { @@ -258,6 +266,7 @@ export class Identifier { } public static isValidHANDLE(str: string): boolean { + // let exp = /\b[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g; // resolve with url - need to add method for raw value let exp = /^[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g; return str.match(exp) != null; } @@ -272,6 +281,28 @@ export class Identifier { let exp = /swh:1:snp:[0-9a-f]{40}/g; return str.match(exp) != null; } + + public static isValidRor(str: string): boolean { + let exp = /0[a-z|0-9]{6}[0-9]{2}\b/g; + return str.match(exp) != null; + } + + public static isValidIsni(str: string): boolean { + let exp = /^[0]{7}[0-9]{8}[0-9X]$/g; + return str.match(exp) != null; + } + + public static isValidWikidata(str: string): boolean { + let exp = /^Q\d+$/g; + return str.match(exp) != null; + } + + public static isValidFundRef(str: string): boolean { + // let exp = /aaa/g; + let exp = /^[1-9]\d+$/g; + return str.match(exp) != null; + } + } export class StringUtils { diff --git a/utils/transition-group/transition-group.component.ts b/utils/transition-group/transition-group.component.ts index 53530868..8cea910d 100644 --- a/utils/transition-group/transition-group.component.ts +++ b/utils/transition-group/transition-group.component.ts @@ -1,6 +1,6 @@ import {TransitionGroupItemDirective} from "./transition-group-item.directive"; import { - AfterViewInit, + AfterViewInit, ChangeDetectorRef, Component, ContentChildren, ElementRef, Input, @@ -29,15 +29,14 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { @ContentChildren(TransitionGroupItemDirective) items: QueryList; @Input() public id: string; - private disabled: boolean = false; + public size: number; private subscription: Subscription; constructor(public element: ElementRef) {} ngAfterViewInit() { - this.init(); this.subscription = this.items.changes.subscribe(items => { - if(!this.disabled) { + if(items.length === this.size) { items.forEach(item => item.prevPos = item.newPos || item.prevPos); items.forEach(this.runCallback); this.refreshPosition('newPos'); @@ -80,6 +79,7 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { init() { this.refreshPosition('prevPos'); this.refreshPosition('newPos'); + this.size = this.items.length; } runCallback(item: TransitionGroupItemDirective) { @@ -126,17 +126,17 @@ export class TransitionGroupComponent implements AfterViewInit, OnDestroy { /** * Enable transition - * + * @deprecated * */ enable() { - this.disabled = false; + console.debug('Deprecated') } /** * Disable transition - * + * @deprecated * */ disable() { - this.disabled = true; + console.debug('Deprecated') } }