Merge pull request 'Merge develop into angular-16-irish-monitor branch' #26

Closed
argiro.kokogiannaki wants to merge 108 commits from develop into angular-16-irish-monitor
137 changed files with 2632 additions and 2265 deletions

View File

@ -28,6 +28,7 @@ export class ClaimResult {
export class ClaimProject { export class ClaimProject {
public funderId: string; public funderId: string;
public funderShortname: string;
public funderName: string; public funderName: string;
public acronym: string; public acronym: string;
public startDate: string; public startDate: string;
@ -92,6 +93,7 @@ export class ClaimRecord2Insert {
targetAccessRights: string; targetAccessRights: string;
targetEmbargoEndDate: string; targetEmbargoEndDate: string;
claimedInDashboard: string; claimedInDashboard: string;
idSuffix:string;
constructor() { constructor() {

View File

@ -65,35 +65,36 @@ export class ClaimProjectsSearchFormComponent {
} }
search(page,size) { search(page,size) {
if(this.keyword.length == 0){ if (this.keyword.length == 0) {
this.showResults =false; this.showResults = false;
return; return;
} }
this.showResults =true; this.showResults = true;
this.openaireResults = []; this.openaireResults = [];
this.openaireResultsStatus = this.errorCodes.LOADING; this.openaireResultsStatus = this.errorCodes.LOADING;
this.prevFilters = this.filters; this.prevFilters = this.filters;
//searchProjects (params: string, refineParams:string, page: number, size: number, refineFields:string[] , properties:EnvProperties ):any { //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 => { data => {
if(data != null) { if (data != null) {
this.openaireResultsPage=page; this.openaireResultsPage = page;
this.openaireResultsNum = data[0]; this.openaireResultsNum = data[0];
this.openaireResults =ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties); this.openaireResults = ClaimProjectsSearchFormComponent.openaire2ClaimEntity(data[1], this.properties);
if(data[2] && data[2].length > 0){ if (data[2] && data[2].length > 0) {
this.filters = this.checkSelectedFilters( data[2], this.prevFilters); 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;
} }
},
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 => { err => {
this.openaireResultsStatus = this.errorCodes.ERROR; this.openaireResultsStatus = this.errorCodes.ERROR;
//console.log(err.status); //console.log(err.status);
@ -177,9 +178,10 @@ export class ClaimProjectsSearchFormComponent {
const entity: ClaimEntity = new ClaimEntity(); const entity: ClaimEntity = new ClaimEntity();
entity.project = new ClaimProject(); entity.project = new ClaimProject();
entity.project.funderId = item.funderId; 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.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.title = item.title.name;
entity.project.acronym = item.acronym; entity.project.acronym = item.acronym;
entity.project.startDate = item.startYear; entity.project.startDate = item.startYear;
@ -202,12 +204,16 @@ export class ClaimProjectsSearchFormComponent {
} }
createOpenaireQueryParams():string { createOpenaireQueryParams(): string {
let query = ""; let query = "";
if(this.keyword.length > 0){ if (this.keyword.length > 0) {
query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword)); // query += "q=" + StringUtils.quote(StringUtils.URIEncode(this.keyword));
query += StringUtils.quote(StringUtils.URIEncode(this.keyword));
} }
return query;
}
createOpenaireRefineQuery(): string {
/*if(this.startYear.length > 0 ){ /*if(this.startYear.length > 0 ){
query+='&fq=projectstartyear exact \"'+this.startYear+'\"' query+='&fq=projectstartyear exact \"'+this.startYear+'\"'
} }
@ -215,30 +221,30 @@ export class ClaimProjectsSearchFormComponent {
query+='&fq=projectendyear exact \"'+this.endYear+'\"' query+='&fq=projectendyear exact \"'+this.endYear+'\"'
}*/ }*/
let allFqs = ""; let allFqs = "";
for (let filter of this.filters){ for (let filter of this.filters) {
if(filter.countSelectedValues > 0){ if (filter.countSelectedValues > 0) {
let count_selected=0; let count_selected = 0;
let fq = ""; let fq = "";
for (let value of filter.values){ for (let value of filter.values) {
if(value.selected == true){ if (value.selected == true) {
count_selected++; 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){ if (count_selected > 0) {
fq="&fq="+StringUtils.URIEncode(fq); fq = "&fq=" + StringUtils.URIEncode(fq);
allFqs += fq; allFqs += fq;
} }
} }
} }
for (let i=0; i<this.rangeFilters.length; i++){ for (let i = 0; i < this.rangeFilters.length; i++) {
let filter = this.rangeFilters[i]; let filter = this.rangeFilters[i];
//selectedFromValue, selectedToValue, equalityOp, equalityOpFrom, equalityOpTo, filterOp ){ //selectedFromValue, selectedToValue, equalityOp, equalityOpFrom, equalityOpTo, filterOp ){
allFqs+= NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i],filter.selectedFromValue, filter.selectedToValue, " within ", ">=" ,"<=", "and" ) allFqs += NewSearchPageComponent.createRangeFilterQuery(this.rangeFields[i], filter.selectedFromValue, filter.selectedToValue, " within ", ">=", "<=", "and")
} }
return query+allFqs; return allFqs + "&type=projects";
} }
public yearChanged() { public yearChanged() {
this.search(this.page, this.size); this.search(this.page, this.size);
@ -273,20 +279,21 @@ export class ClaimProjectsSearchFormComponent {
} }
} }
filter.countAllValues = filter.values.length;
} }
if(filters.length == 0 ){ if(filters.length == 0 ){
for(let j=0; j< prevFilters.length ; j++){ for(let j=0; j< prevFilters.length ; j++) {
let filter = Object.assign({}, prevFilters[j]); let filter = Object.assign({}, prevFilters[j]);
filter.values = []; filter.values = [];
for(let filterValue of prevFilters[j].values) { for (let filterValue of prevFilters[j].values) {
if(filterValue.selected){ if (filterValue.selected) {
filterValue.number = 0; filterValue.number = 0;
filter.values.push(filterValue); filter.values.push(filterValue);
}
}
filters.push(filter)
} }
}
filter.countAllValues = filter.values.length;
filters.push(filter)
}
} }
return filters; return filters;
} }

View File

@ -56,57 +56,76 @@
<div *ngIf="claims && claims.length == 0" class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold"> <div *ngIf="claims && claims.length == 0" class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div>No links found</div> <div>No links found</div>
</div> </div>
<ul class="uk-margin-small-top uk-list uk-list-xlarge"> <ng-container *ngIf="claims && claims.length > 0">
<li *ngFor="let claim of claims; let i=index" class="uk-card uk-card-default">
<div class="uk-card-body"> <div class="uk-flex uk-flex-middle uk-margin-top uk-margin-small-bottom uk-padding-small uk-padding-remove-horizontal">
<div class="uk-grid uk-grid-small" uk-grid> <div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<div class="uk-width-expand"> <label>
<div class="uk-margin-bottom"> <input id="checkAll" type="checkbox" (click)="selectAll($event)" class="uk-checkbox" title="Select All"
<claim-entity [entity]="claim.target" [type]="claim.targetType" [properties]=properties [ngModel]="selected.length == claims.length"/>
[externalPortalUrl]=externalPortalUrl [source]="true" [linkAvailable]="isClaimAvailable(claim)"></claim-entity> </label>
</div> </div>
<div class="uk-margin-bottom"> <button class="uk-button uk-button-link" [class.uk-disabled]="selected.length == 0" [disabled]="selected.length == 0"
<span *ngIf="isClaimAvailable(claim) else notAvailable" class="uk-label uk-label-success" (click)="deleteOpen()">
[attr.uk-tooltip]="'title: The link information is available in the portal and the APIs.'">available</span> <span>Delete ({{selected.length}})</span>
<ng-template #notAvailable> </button>
<span class="uk-label uk-label-danger" </div>
[attr.uk-tooltip]="'title:The link information will be added in the portal and the APIs in the next content provision workflow.'">pending</span>
</ng-template> <ul class="uk-margin-small-top uk-list uk-list-striped">
</div> <li *ngFor="let claim of claims; let i=index" class="uk-flex uk-flex-middle uk-padding-small uk-padding-remove-horizontal">
<div class="uk-text-small"> <div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<div *ngIf="showUserEmail" class="uk-margin-small-bottom"> <input type="checkbox" class="uk-checkbox"
<span class="uk-text-meta">Claimed by:</span> [id]="claim.id" (click)="selectClaim(claim, $event)" [ngModel]="isSelectedClaim(claim.id)">
<span class="uk-margin-xsmall-left">{{claim.userMail}}</span> </div>
<div class="uk-width-expand">
<div class="uk-grid uk-grid-small uk-flex-middle" uk-grid>
<div class="uk-width-expand">
<div class="uk-margin-small-bottom">
<claim-entity [entity]="claim.target" [type]="claim.targetType" [properties]=properties
[externalPortalUrl]=externalPortalUrl [source]="true" [linkAvailable]="isClaimAvailable(claim)"></claim-entity>
</div> </div>
<div> <div class="uk-margin-small-bottom">
<span class="uk-text-meta">Claimed date:</span> <span *ngIf="isClaimAvailable(claim) else notAvailable" class="uk-label uk-label-small uk-label-success"
<span class="uk-margin-xsmall-left">{{claim.date}}</span> [attr.uk-tooltip]="'title: The link information is available in the portal and the APIs.'">available</span>
<ng-template #notAvailable>
<span class="uk-label uk-label-small uk-label-danger"
[attr.uk-tooltip]="'title:The link information will be added in the portal and the APIs in the next content provision workflow.'">pending</span>
</ng-template>
</div>
<div class="uk-text-small">
<div *ngIf="showUserEmail" class="uk-margin-xsmall-bottom">
<span class="uk-text-meta">Claimed by:</span>
<span class="uk-margin-xsmall-left">{{claim.userMail}}</span>
</div>
<div>
<span class="uk-text-meta">Claimed date:</span>
<span class="uk-margin-xsmall-left">{{claim.date}}</span>
</div>
</div> </div>
</div> </div>
</div> <div class="uk-visible@m">
<div class="uk-visible@m"> <div class="claim-divider">
<div class="claim-divider"> <icon class="uk-position-center" name="link" customClass="uk-text-primary" ratio="2" [flex]="true"></icon>
<icon class="uk-position-center" name="link" customClass="uk-text-primary" ratio="2" [flex]="true"></icon> </div>
</div>
<div class="uk-width-1-2@m uk-width-1-1">
<claim-entity [entity]="claim.source" [type]="claim.sourceType" [source]="false" [properties]=properties
[externalPortalUrl]=externalPortalUrl></claim-entity>
</div> </div>
</div>
<div class="uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-column uk-flex-center">
<claim-entity [entity]="claim.source" [type]="claim.sourceType" [source]="false" [properties]=properties
[externalPortalUrl]=externalPortalUrl></claim-entity>
</div> </div>
</div> </div>
</div> <div class="uk-width-xsmall uk-flex uk-flex-center uk-flex-middle">
<div class="uk-card-footer uk-flex uk-flex-right"> <button class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="deleteOpen(i)">
<button class="uk-button uk-button-link uk-flex uk-flex-middle" (click)="deleteOpen(i)"> <icon name="delete" [flex]="true"></icon>
<icon name="delete" [flex]="true"></icon> </button>
<span class="uk-margin-xsmall-left">Delete</span> </div>
</button> </li>
</div> </ul>
</li> <div class="uk-margin-medium-top uk-flex uk-flex-center uk-flex-right@m">
</ul> <paging-no-load *ngIf="resultsNum" [currentPage]="page" [totalResults]="resultsNum" [size]="size"
<div class="uk-margin-medium-top uk-flex uk-flex-center uk-flex-right@m"> (pageChange)="pageChange($event)"></paging-no-load>
<paging-no-load *ngIf="resultsNum" [currentPage]="page" [totalResults]="resultsNum" [size]="size" </div>
(pageChange)="pageChange($event)"></paging-no-load> </ng-container>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -4,14 +4,4 @@
position: relative; position: relative;
padding: 0 20px; padding: 0 20px;
height: 100%; height: 100%;
&::before {
content: '';
position: absolute;
top: 0;
left: 50%;
right: 0;
bottom: 0;
border-left: @global-border-width solid @global-border;
}
} }

View File

@ -52,6 +52,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
lastIndexDate = null; lastIndexDate = null;
public filterForm: FormGroup; public filterForm: FormGroup;
public entities: string[] = []; public entities: string[] = [];
selected = [];
allOptions: Option[] = [ allOptions: Option[] = [
{label: OpenaireEntities.PUBLICATIONS, value: "publication"}, {label: OpenaireEntities.PUBLICATIONS, value: "publication"},
@ -310,23 +311,34 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
} }
isSelected(value: string) { 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.index = index;
this.deleteModal.alertTitle = 'Delete Confirmation'; 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.okButtonText = 'Yes';
this.deleteModal.open(); this.deleteModal.open();
} }
delete() { 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 => { res => {
this.claims.splice(this.index, 1); if (this.index != null) {
this.resultsNum = this.resultsNum - 1; this.claims.splice(this.index, 1);
NotificationHandler.rise('Link has been deleted successfully'); 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; let goToPage = this.page;
if (this.totalPages(this.resultsNum) < this.page && this.page > 0) { if (this.totalPages(this.resultsNum) < this.page && this.page > 0) {
goToPage = this.page - 1; goToPage = this.page - 1;
@ -334,7 +346,8 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
this.goTo(goToPage); this.goTo(goToPage);
}, err => { }, err => {
this.handleErrors(err, "Error deleting claim with id: " + this.claims[this.index].id); this.handleErrors(err, "Error deleting claim with id: " + this.claims[this.index].id);
})); }
));
} }
pageChange($event) { pageChange($event) {
@ -351,7 +364,7 @@ export class DisplayClaimsComponent implements OnInit, OnDestroy {
if (claimDateStr < lastUpdateDateStr) { if (claimDateStr < lastUpdateDateStr) {
return true; return true;
} else { } 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; 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) { private updateDescription(description: string) {
this._meta.updateTag({content: description}, "name='description'"); this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'"); this._meta.updateTag({content: description}, "property='og:description'");

View File

@ -17,7 +17,6 @@ import {HelperModule} from '../../../utils/helper/helper.module';
import {Schema2jsonldModule} from '../../../sharedComponents/schema2jsonld/schema2jsonld.module'; import {Schema2jsonldModule} from '../../../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../../../sharedComponents/SEO/SEOService.module'; import { SEOServiceModule } from '../../../sharedComponents/SEO/SEOService.module';
import {IndexInfoServiceModule} from "../../../utils/indexInfoService.module"; import {IndexInfoServiceModule} from "../../../utils/indexInfoService.module";
import {PiwikServiceModule} from "../../../utils/piwik/piwikService.module";
import {SearchInputModule} from '../../../sharedComponents/search-input/search-input.module'; import {SearchInputModule} from '../../../sharedComponents/search-input/search-input.module';
import {InputModule} from '../../../sharedComponents/input/input.module'; import {InputModule} from '../../../sharedComponents/input/input.module';
import {LoadingModule} from '../../../utils/loading/loading.module'; import {LoadingModule} from '../../../utils/loading/loading.module';
@ -30,7 +29,7 @@ import {link} from "../../../utils/icons/icons";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, RouterModule, ClaimServiceModule, LoadingModalModule, AlertModalModule, 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 IndexInfoServiceModule, MatSelectModule, SearchInputModule, MatAutocompleteModule, MatChipsModule, MatFormFieldModule, MatSlideToggleModule, InputModule, LoadingModule, NoLoadPaging, IconsModule, DropdownFilterModule
], ],

View File

@ -15,21 +15,22 @@ import {StringUtils} from "../../../utils/string-utils.class";
<div *ngIf="source" class="uk-text-small"> <div *ngIf="source" class="uk-text-small">
{{getEntityName(type)}} {{getEntityName(type)}}
</div> </div>
<div class="uk-flex"> <div>
<span *ngIf="!source" class="uk-text-meta uk-margin-small-right uk-text-large uk-text-nowrap">Link to:</span> <span *ngIf="!source" class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<publication-title [entity]="entity" param="id" <publication-title [entity]="entity" param="id"
path="/search/result" [externalPortalUrl]=externalPortalUrl [linkAvailable]="linkAvailable"></publication-title> path="/search/result" [externalPortalUrl]=externalPortalUrl [linkAvailable]="linkAvailable"></publication-title>
</div> </div>
</div> </div>
<div *ngIf="type == 'project'" [attr.uk-tooptip]="getEntityName(type)" <div *ngIf="type == 'project'" [attr.uk-tooptip]="getEntityName(type)">
class="uk-flex"> <span class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<span class="uk-text-meta uk-margin-small-right uk-text-large uk-text-nowrap">Link to:</span>
<project-title [project]="entity" [searchLink]=properties.searchLinkToProject <project-title [project]="entity" [searchLink]=properties.searchLinkToProject
[externalPortalUrl]=externalPortalUrl></project-title> [externalPortalUrl]=externalPortalUrl></project-title>
</div> </div>
<div *ngIf="type == 'context'" class="uk-flex uk-text-large"> <div *ngIf="type == 'context'">
<span class="uk-text-meta uk-margin-small-right uk-text-nowrap">Link to:</span> <span class="uk-text-meta uk-text-small uk-margin-small-right uk-text-nowrap">Link to:</span>
<span class="uk-text-truncate" uk-tooltip="Concept">{{entity.title}}</span> <h6 class="uk-h6 uk-margin-remove">
<span class="uk-text-truncate" uk-tooltip="Concept">{{entity.title}}</span>
</h6>
</div> </div>
` `
}) })

View File

@ -20,7 +20,7 @@ import {properties} from "../../../../../environments/environment";
</h6> </h6>
</ng-container> </ng-container>
<span *ngIf="project['funderName']" class="uk-margin-small-top"> <span *ngIf="project['funderName']" class="uk-margin-small-top">
<span class="uk-text-muted">Funder: </span>{{project['funderName']}} <span class="uk-text-meta">Funder: </span>{{project['funderName']}}
</span> </span>
` `
}) })

View File

@ -58,22 +58,20 @@ export class SearchDataciteService {
entity.result.journal = null; entity.result.journal = null;
entity.result.DOI = item.attributes.doi; entity.result.DOI = item.attributes.doi;
entity.id = 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.url = properties.doiURL + item.attributes.doi;
entity.result.source = 'datacite'; entity.result.source = 'datacite';
entity.type = 'dataset'; entity.type = 'dataset';
entity.result.date = item.attributes.published; entity.result.date = item.attributes.publicationYear;
entity.result.accessRights = "OPEN"; entity.result.accessRights = "OPEN";
entity.result.publisher = item.attributes['container-title']; entity.result.publisher = item.attributes['publisher'];
entity.result.journal = null; entity.result.journal = null;
entity.result.record = item; entity.result.record = item;
if (item.attributes.author) { if (item.attributes.creators) {
entity.result.authors = []; entity.result.authors = [];
for (let j = 0; j < item.attributes.author.length; j++) { for (let j = 0; j < item.attributes.creators.length; j++) {
const author = item.attributes.author[j]; const author = item.attributes.creators[j].name;
if(author.family || author.literal) { entity.result.authors.push(author);
entity.result.authors.push((author.family) ? author.family + (author.given ? ', ' + author.given : '') : author.literal);
}
} }
} }
results.push(entity); results.push(entity);

View File

@ -3,9 +3,6 @@ import { NgModule } from '@angular/core';
import { SharedModule } from '../../../openaireLibrary/shared/shared.module'; import { SharedModule } from '../../../openaireLibrary/shared/shared.module';
import { ClaimsAdminComponent } from './claimsAdmin.component'; import { ClaimsAdminComponent } from './claimsAdmin.component';
import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; 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({ @NgModule({
imports: [ imports: [
@ -13,7 +10,7 @@ import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
DisplayClaimsModule DisplayClaimsModule
], ],
providers:[AdminLoginGuard, PreviousRouteRecorder,IsRouteEnabled], providers:[],
declarations: [ declarations: [
ClaimsAdminComponent ClaimsAdminComponent
], ],

View File

@ -156,6 +156,7 @@ export class DirectLinkingComponent {
entity.project.code = project.code; entity.project.code = project.code;
entity.project.endDate = project.endDate; entity.project.endDate = project.endDate;
entity.project.funderId = project.funderId; entity.project.funderId = project.funderId;
entity.project.funderShortname = project.funderShortName?project.funderShortName:(entity.project.funderId.split("::")[1]);
entity.project.funderName = project.funderName; entity.project.funderName = project.funderName;
entity.project.fundingLevel0 = project.fundingLevel0; entity.project.fundingLevel0 = project.fundingLevel0;
entity.project.jurisdiction = project.jurisdiction; entity.project.jurisdiction = project.jurisdiction;

View File

@ -5,9 +5,6 @@ import { DirectLinkingComponent } from './directLinking.component';
import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module'; import {EntitySearchServiceModule} from '../../utils/entitiesAutoComplete/entitySearchService.module';
import {SearchResearchResultsServiceModule} from '../../services/searchResearchResultsService.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 {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module'; import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module';
import {LinkingGenericModule} from '../linking/linkingGeneric.module'; import {LinkingGenericModule} from '../linking/linkingGeneric.module';
@ -18,7 +15,7 @@ import {LinkingGenericModule} from '../linking/linkingGeneric.module';
EntitySearchServiceModule, SearchResearchResultsServiceModule, EntitySearchServiceModule, SearchResearchResultsServiceModule,
Schema2jsonldModule, SEOServiceModule, LinkingGenericModule Schema2jsonldModule, SEOServiceModule, LinkingGenericModule
], ],
providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], providers:[],
declarations: [ declarations: [
DirectLinkingComponent DirectLinkingComponent
], exports:[DirectLinkingComponent] ], exports:[DirectLinkingComponent]

View File

@ -269,11 +269,16 @@ export class BulkClaimComponent {
} }
}, },
err => { err => {
//console.log(err); // console.log(err);
BulkClaimComponent.handleError("Error getting crossref by DOIs: " + id, err); BulkClaimComponent.handleError("Error getting crossref by DOIs: " + id, err);
this.notFoundIds.push(id);
this.notFoundIdsRow.push(row); if(err.status == 404) {
this.endOfFetching(); this.searchInDatacite(id, accessMode, date, row);
} else {
this.notFoundIds.push(id);
this.notFoundIdsRow.push(row);
this.endOfFetching();
}
} }
)); ));
} }

View File

@ -156,13 +156,14 @@ export class ClaimInsertComponent {
this.loading.open(); this.loading.open();
let claims: ClaimRecord2Insert[] = []; let claims: ClaimRecord2Insert[] = [];
let directclaims: DirectIndexRecord[] = []; let directclaims: DirectIndexRecord[] = [];
let idSuffix = (new Date()).getTime() + "";
let dashboard = this.properties.environment+"_"+this.properties.dashboard + (this.communityId?("_"+this.communityId):''); 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 for (let j = 0; j < this.sources.length; j++) { // if an external result -> direct insert in the index
const result: ClaimEntity = this.sources[j]; const result: ClaimEntity = this.sources[j];
if (result.result && ["crossref", "datacite", "orcid"].indexOf(result.result.source) != -1) { if (result.result && ["crossref", "datacite", "orcid"].indexOf(result.result.source) != -1) {
directclaims.push({ directclaims.push({
"id": result.id, "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) { if (this.sources.length > 0) {
directclaims.push({ directclaims.push({
"id": entity.id, "id": entity.id,
"record": ClaimInsertComponent.createDirectClaim(entity, this.sources) "record": ClaimInsertComponent.createDirectClaim(entity, this.sources, idSuffix)
}); });
} else if (this.inlineEntity) { } else if (this.inlineEntity) {
directclaims.push({ directclaims.push({
"id": entity.id, "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++) { for (let j = 0; j < this.sources.length; j++) {
const result: ClaimEntity = this.sources[j]; // this is a research result const result: ClaimEntity = this.sources[j]; // this is a research result
if (entity.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) { } 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) { } 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]); 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 (this.inlineEntity.result) {
if (entity.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) { } 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) { } 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) { } else if (this.inlineEntity.project) {
if (entity.result) { 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 { return {
claimedBy: user, claimedBy: user,
sourceId: contextEntity.context.concept.id, sourceId: contextEntity.context.concept.id,
@ -403,11 +404,12 @@ export class ClaimInsertComponent {
targetCollectedFrom: resultEntity.result.source, targetCollectedFrom: resultEntity.result.source,
targetAccessRights: resultEntity.result.accessRights, targetAccessRights: resultEntity.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity), 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 { return {
claimedBy: user, claimedBy: user,
sourceId: projectEntity.id, sourceId: projectEntity.id,
@ -420,11 +422,12 @@ export class ClaimInsertComponent {
targetCollectedFrom: resultEntity.result.source, targetCollectedFrom: resultEntity.result.source,
targetAccessRights: resultEntity.result.accessRights, targetAccessRights: resultEntity.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(resultEntity), 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 { return {
claimedBy: user, claimedBy: user,
@ -438,7 +441,9 @@ export class ClaimInsertComponent {
targetCollectedFrom: inlineResult.result.source, targetCollectedFrom: inlineResult.result.source,
targetAccessRights: inlineResult.result.accessRights, targetAccessRights: inlineResult.result.accessRights,
targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(inlineResult), targetEmbargoEndDate: ClaimInsertComponent.getEmbargoEndDate(inlineResult),
claimedInDashboard : dashboard claimedInDashboard : dashboard,
idSuffix : idSuffix
}; };
} }
@ -448,12 +453,13 @@ export class ClaimInsertComponent {
} }
return "" return ""
} }
static createOpenAIREId(id, idSuffix:string):string {
static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[]) { return id.indexOf( "::" ) == -1 ? ("userclaim___::" + Md5.hashStr(id + idSuffix)):id;
}
static createDirectClaim(resultEntity: ClaimEntity, results: ClaimEntity[], idSuffix:string) {
let entity = {}; let entity = {};
const md5_id = Md5.hashStr(resultEntity.id); entity["originalId"] = this.createOpenAIREId(resultEntity.id, idSuffix);
entity["originalId"] = "userclaim___::" + md5_id; entity["openaireId"] = this.createOpenAIREId(resultEntity.id, idSuffix);
entity["openaireId"] = "userclaim___::" + md5_id;
entity["title"] = resultEntity.title; entity["title"] = resultEntity.title;
entity["title"] = (Array.isArray(resultEntity.title) && resultEntity.title.length > 0) ? resultEntity.title[0] : 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"] = []; entity["linksToProjects"] = [];
} }
let project: ClaimEntity = results[i]; 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) { } else if (results[i].context) {

View File

@ -7,20 +7,16 @@ import {SelectedContextsModule} from './selected/selectedContexts.module';
import {SelectedPublicationsModule} from './selected/selectedResults.module'; import {SelectedPublicationsModule} from './selected/selectedResults.module';
import {LinkingGenericComponent} from './linkingGeneric.component'; import {LinkingGenericComponent} from './linkingGeneric.component';
import {StartOverModule} from '../claim-utils/startOver.module'; 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 {ClaimContextSearchFormModule} from '../claim-utils/claimContextSearchForm.module';
import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module'; import {ClaimProjectsSearchFormModule} from '../claim-utils/claimProjectSearchForm.module';
import {BulkClaimModule} from './bulkClaim/bulkClaim.module'; import {BulkClaimModule} from './bulkClaim/bulkClaim.module';
import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module'; import {ClaimResultSearchFormModule} from '../claim-utils/claimResultSearchForm.module';
import {HelperModule} from '../../utils/helper/helper.module'; import {HelperModule} from '../../utils/helper/helper.module';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module'; import {SEOServiceModule} from '../../sharedComponents/SEO/SEOService.module';
import {MetadataPreviewModule} from './selected/metadataPreview.module'; import {MetadataPreviewModule} from './selected/metadataPreview.module';
import {ClaimEntitiesMetadataModule} from "./selected/ClaimEntitiesMetadata.module"; import {ClaimEntitiesMetadataModule} from "./selected/ClaimEntitiesMetadata.module";
import {AlertModalModule} from '../../utils/modal/alertModal.module'; import {AlertModalModule} from '../../utils/modal/alertModal.module';
import {PiwikServiceModule} from "../../utils/piwik/piwikService.module";
import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module"; import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module";
import {StepperModule} from "../../sharedComponents/stepper/stepper.module"; import {StepperModule} from "../../sharedComponents/stepper/stepper.module";
import {IconsModule} from "../../utils/icons/icons.module"; import {IconsModule} from "../../utils/icons/icons.module";
@ -34,10 +30,9 @@ import {link} from "../../utils/icons/icons";
StartOverModule, StartOverModule,
ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule, ClaimContextSearchFormModule, ClaimProjectsSearchFormModule, BulkClaimModule, ClaimResultSearchFormModule,
HelperModule, Schema2jsonldModule, SEOServiceModule, MetadataPreviewModule, ClaimEntitiesMetadataModule, AlertModalModule, HelperModule, Schema2jsonldModule, SEOServiceModule, MetadataPreviewModule, ClaimEntitiesMetadataModule, AlertModalModule,
PiwikServiceModule,
MatSelectModule, BreadcrumbsModule, StepperModule, IconsModule MatSelectModule, BreadcrumbsModule, StepperModule, IconsModule
], ],
providers: [LoginGuard, PreviousRouteRecorder, IsRouteEnabled], providers: [],
declarations: [ declarations: [
LinkingGenericComponent LinkingGenericComponent
], exports: [ ], exports: [

View File

@ -16,10 +16,10 @@ import {ClaimEntity} from '../../claim-utils/claimHelper.class';
</div> </div>
<div class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'" <div class="uk-text-small uk-flex uk-flex-wrap" [style.grid-gap]="shortVersion?'10px':'20px'"
[class.uk-margin-small-top]="!shortVersion"> [class.uk-margin-small-top]="!shortVersion">
<div *ngIf="entity.project.funderName"> <div *ngIf="entity.project.funderName || entity.project.funderShortname">
<span class="uk-text-meta">Funder: </span>{{entity.project.funderName}} <span class="uk-text-meta">Funder: </span>{{entity.project.funderName?entity.project.funderName:entity.project.funderShortname}}
</div> </div>
<div *ngIf="entity.project.code"> <div *ngIf="entity.project.code && entity.project.code!='unidentified'">
<span class="uk-text-meta">Project Code: </span>{{entity.project.code}} <span class="uk-text-meta">Project Code: </span>{{entity.project.code}}
</div> </div>
</div> </div>

View File

@ -3,9 +3,6 @@ import { NgModule } from '@angular/core';
import { SharedModule } from '../../../openaireLibrary/shared/shared.module'; import { SharedModule } from '../../../openaireLibrary/shared/shared.module';
import { MyClaimsComponent } from './myClaims.component'; import { MyClaimsComponent } from './myClaims.component';
import {DisplayClaimsModule} from '../claim-utils/displayClaims/displayClaims.module'; 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({ @NgModule({
imports: [ imports: [
@ -13,7 +10,7 @@ import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
DisplayClaimsModule DisplayClaimsModule
], ],
providers:[LoginGuard, PreviousRouteRecorder, IsRouteEnabled], providers:[],
declarations: [ declarations: [
MyClaimsComponent MyClaimsComponent
], exports: [MyClaimsComponent] ], exports: [MyClaimsComponent]

View File

@ -15,9 +15,10 @@ import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({ @NgModule({
imports: [ imports: [
ClassesRoutingModule,
CommonModule, RouterModule, FormsModule, CommonModule, RouterModule, FormsModule,
AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule,
AdminTabsModule, PageContentModule, ClassesRoutingModule, SearchInputModule, IconsModule, LoadingModule AdminTabsModule, PageContentModule, SearchInputModule, IconsModule, LoadingModule
], ],
declarations: [DivIdsComponent], declarations: [DivIdsComponent],
exports: [DivIdsComponent] exports: [DivIdsComponent]

View File

@ -16,9 +16,10 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m
@NgModule({ @NgModule({
imports: [ imports: [
ClassHelpContentFormRoutingModule,
CommonModule, FormsModule, RouterModule, CommonModule, FormsModule, RouterModule,
SafeHtmlPipeModule, CKEditorModule, SafeHtmlPipeModule, CKEditorModule,
AlertModalModule, ReactiveFormsModule, ClassHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, MatSlideToggleModule, IconsModule, LoadingModule, PageContentModule
], ],
declarations: [ declarations: [
ClassContentFormComponent ClassContentFormComponent

View File

@ -19,8 +19,9 @@ import {PageContentModule} from '../sharedComponents/page-content/page-content.m
@NgModule({ @NgModule({
imports: [ imports: [
ClassHelpContentsRoutingModule,
CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule, CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, ClassHelpContentsRoutingModule, AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule,
SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule, PageContentModule SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule, PageContentModule
], ],
declarations: [ declarations: [

View File

@ -17,8 +17,9 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
@NgModule({ @NgModule({
imports: [ imports: [
EntitiesRoutingModule,
CommonModule, RouterModule, FormsModule, AdminToolServiceModule, 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], declarations: [EntitiesComponent],
exports: [EntitiesComponent] exports: [EntitiesComponent]

View File

@ -16,9 +16,10 @@ import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({ @NgModule({
imports: [ imports: [
PageHelpContentFormRoutingModule,
CommonModule, FormsModule, RouterModule, CommonModule, FormsModule, RouterModule,
SafeHtmlPipeModule, CKEditorModule, SafeHtmlPipeModule, CKEditorModule,
AlertModalModule, ReactiveFormsModule, PageHelpContentFormRoutingModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule AlertModalModule, ReactiveFormsModule, AdminToolServiceModule, InputModule, IconsModule, PageContentModule, LoadingModule, MatSlideToggleModule
], ],
declarations: [PageContentFormComponent], declarations: [PageContentFormComponent],
exports: [PageContentFormComponent] exports: [PageContentFormComponent]

View File

@ -17,8 +17,9 @@ import {HTMLToStringPipeModule} from '../../utils/pipes/HTMLToStringPipe.module'
@NgModule({ @NgModule({
imports: [ imports: [
PageHelpContentsRoutingModule,
CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule, CommonModule, RouterModule, FormsModule, SafeHtmlPipeModule,
AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageHelpContentsRoutingModule, PageContentModule, AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, PageContentModule,
SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule SearchInputModule, IconsModule, LoadingModule, HTMLToStringPipeModule
], ],
declarations: [ declarations: [

View File

@ -372,10 +372,8 @@ export class MenuComponent implements OnInit {
} }
public valueChange() { public valueChange() {
this.elements.disable();
this.cdr.detectChanges(); this.cdr.detectChanges();
this.elements.init(); this.elements.init();
this.elements.enable();
} }
public get displayMenuItems() { public get displayMenuItems() {

View File

@ -18,8 +18,9 @@ import {LogoUrlPipeModule} from '../../utils/pipes/logoUrlPipe.module';
@NgModule({ @NgModule({
imports: [ imports: [
MenuRoutingModule,
CommonModule, RouterModule, FormsModule, AdminToolServiceModule, 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 TransitionGroupModule, LogoUrlPipeModule
], ],
declarations: [MenuComponent], declarations: [MenuComponent],

View File

@ -20,8 +20,9 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
@NgModule({ @NgModule({
imports: [ imports: [
PagesRoutingModule,
CommonModule, RouterModule, FormsModule, AlertModalModule, ReactiveFormsModule, MatSlideToggleModule, AdminToolServiceModule, InputModule, 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], declarations: [PagesComponent],
exports: [PagesComponent] exports: [PagesComponent]

View File

@ -15,9 +15,10 @@ import {LoadingModule} from "../../utils/loading/loading.module";
@NgModule({ @NgModule({
imports: [ imports: [
PortalsRoutingModule,
CommonModule, FormsModule, AlertModalModule, CommonModule, FormsModule, AlertModalModule,
ReactiveFormsModule, ReactiveFormsModule,
RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, PortalsRoutingModule, IconsModule, SearchInputModule, LoadingModule RouterModule, AdminToolServiceModule, InputModule, AdminTabsModule, PageContentModule, IconsModule, SearchInputModule, LoadingModule
], ],
declarations: [PortalsComponent], declarations: [PortalsComponent],
exports: [PortalsComponent] exports: [PortalsComponent]

View File

@ -88,6 +88,10 @@ export class LayoutService {
* Handle it manually in the component, it doesn't use data * Handle it manually in the component, it doesn't use data
* */ * */
private rootClassSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null); private rootClassSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
/**
* Display help pop-up on non-admin pages. (default true for the rest of the pages)
* */
private hasHelpPopUpSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
private subscriptions: any[] = []; private subscriptions: any[] = [];
ngOnDestroy() { ngOnDestroy() {
@ -343,4 +347,12 @@ export class LayoutService {
this.rootClassSubject.next(value); this.rootClassSubject.next(value);
} }
} }
get hasHelpPopUp(): Observable<boolean> {
return this.hasHelpPopUpSubject.asObservable();
}
setHasHelpPopUp(value: boolean) {
this.hasHelpPopUpSubject.next(value);
}
} }

View File

@ -8,26 +8,26 @@
<div class="uk-flex uk-flex-left@m uk-flex-center uk-width-expand"> <div class="uk-flex uk-flex-left@m uk-flex-center uk-width-expand">
<ul class="uk-subnav uk-subnav-pill"> <ul class="uk-subnav uk-subnav-pill">
<li [class.uk-active]="showCurrent" (click)="showCurrent = true"> <li [class.uk-active]="showCurrent" (click)="showCurrent = true">
<a class="uk-text-capitalize">{{role}}s</a> <a class="uk-text-capitalize">{{stakeholderUtils.roles[role]}}s</a>
</li> </li>
<li [class.uk-active]="!showCurrent" (click)="showCurrent = false"> <li [class.uk-active]="!showCurrent" (click)="showCurrent = false">
<a>Pending {{role}}s</a> <a>Pending {{stakeholderUtils.roles[role]}}s</a>
</li> </li>
</ul> </ul>
</div> </div>
<div class="uk-width-expand@m uk-width-1-1 uk-grid uk-flex-right@m uk-flex-center uk-flex-middle" uk-grid> <div class="uk-width-expand@m uk-width-1-1 uk-grid uk-flex-right@m uk-flex-center uk-flex-middle" uk-grid>
<div *ngIf="showCurrent" [disabled]="loadActive" search-input class="uk-width-expand@l uk-width-1-1" <div *ngIf="showCurrent" [disabled]="loadActive" search-input class="uk-width-expand@l uk-width-1-1"
[searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + role + 's'" searchInputClass="outer"> [searchControl]="filterForm.get('active')" [expandable]="true" [placeholder]="'Search ' + stakeholderUtils.roles[role] + 's'" searchInputClass="outer">
</div> </div>
<div *ngIf="!showCurrent" [disabled]="loadPending" search-input class="uk-width-expand@l uk-width-1-1" <div *ngIf="!showCurrent" [disabled]="loadPending" search-input class="uk-width-expand@l uk-width-1-1"
[searchControl]="filterForm.get('pending')" [expandable]="true" [placeholder]="'Search invitations'" searchInputClass="outer"> [searchControl]="filterForm.get('pending')" [expandable]="true" [placeholder]="'Search invitations'" searchInputClass="outer">
</div> </div>
<div> <div>
<button *ngIf="exists" class="uk-button uk-button-default uk-flex uk-flex-middle" <button *ngIf="canInvite" class="uk-button uk-button-default uk-flex uk-flex-middle"
[attr.uk-tooltip]="inviteDisableMessage" [class.uk-disabled]="loadPending || loadPending" [attr.uk-tooltip]="inviteDisableMessage" [class.uk-disabled]="loadPending || loadPending"
[disabled]="loadActive || loadPending || !!inviteDisableMessage" (click)="openInviteModal()"> [disabled]="loadActive || loadPending || !!inviteDisableMessage" (click)="openInviteModal()">
<icon name="person_add" [flex]="true" type="filled"></icon> <icon name="person_add" [flex]="true" type="filled"></icon>
<span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite {{role}}</span> <span class="uk-margin-small-left uk-text-bold uk-text-uppercase">Invite {{stakeholderUtils.roles[role]}}</span>
</button> </button>
<button *ngIf="!exists && isCurator" class="uk-button uk-button-default uk-flex uk-flex-middle" <button *ngIf="!exists && isCurator" class="uk-button uk-button-default uk-flex uk-flex-middle"
(click)="openCreateRoleModal()"> (click)="openCreateRoleModal()">
@ -47,16 +47,16 @@
<div *ngIf="!loadActive && !loadPending"> <div *ngIf="!loadActive && !loadPending">
<div *ngIf="(showCurrent && showActive.length == 0) || (!showCurrent && showPending.length == 0)" <div *ngIf="(showCurrent && showActive.length == 0) || (!showCurrent && showPending.length == 0)"
class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold"> class="uk-card uk-card-default uk-padding-large uk-text-center uk-margin-bottom uk-text-bold">
<div *ngIf="showCurrent">No {{role}}s found</div> <div *ngIf="showCurrent">No {{stakeholderUtils.roles[role]}}s found</div>
<div *ngIf="!showCurrent">No pending {{role}} invitations found</div> <div *ngIf="!showCurrent">No pending {{stakeholderUtils.roles[role]}} invitations found</div>
</div> </div>
<div *ngIf="(showCurrent && showActive.length > 0) || (!showCurrent && showPending.length > 0)"> <div *ngIf="(showCurrent && showActive.length > 0) || (!showCurrent && showPending.length > 0)">
<no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(role + 's'):role" <no-load-paging *ngIf="showCurrent" [type]="(showActive.length > 1)?(stakeholderUtils.roles[role] + 's'):role"
(pageChange)="updateActivePage($event)" (pageChange)="updateActivePage($event)"
[page]="activePage" [pageSize]="pageSize" [page]="activePage" [pageSize]="pageSize"
[totalResults]="showActive.length"> [totalResults]="showActive.length">
</no-load-paging> </no-load-paging>
<no-load-paging *ngIf="!showCurrent" [type]="role + ' ' + (showPending.length > 1?'invitations':'invitation')" <no-load-paging *ngIf="!showCurrent" [type]="stakeholderUtils.roles[role] + ' ' + (showPending.length > 1?'invitations':'invitation')"
(pageChange)="updatePendingPage($event)" (pageChange)="updatePendingPage($event)"
[page]="pendingPage" [pageSize]="pageSize" [page]="pendingPage" [pageSize]="pageSize"
[totalResults]="showPending.length"> [totalResults]="showPending.length">
@ -109,12 +109,12 @@
</modal-alert> </modal-alert>
<modal-alert #deleteModal [overflowBody]="false" (alertOutput)="deleteActive()" classTitle="uk-background-primary uk-light"> <modal-alert #deleteModal [overflowBody]="false" (alertOutput)="deleteActive()" classTitle="uk-background-primary uk-light">
<div *ngIf="selectedUser"> <div *ngIf="selectedUser">
Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from {{role}}s? Are you sure you want to remove <span class="uk-text-bold">{{selectedUser}}</span> from {{stakeholderUtils.roles[role]}}s?
</div> </div>
</modal-alert> </modal-alert>
<modal-alert #deletePendingModal [overflowBody]="false" (alertOutput)="deletePending()" classTitle="uk-background-primary uk-light"> <modal-alert #deletePendingModal [overflowBody]="false" (alertOutput)="deletePending()" classTitle="uk-background-primary uk-light">
<div *ngIf="selectedUser"> <div *ngIf="selectedUser">
Are you sure you want to cancel {{role}} invitation of <span class="uk-text-bold">{{selectedUser}}</span>? Are you sure you want to cancel {{stakeholderUtils.roles[role]}} invitation of <span class="uk-text-bold">{{selectedUser}}</span>?
</div> </div>
</modal-alert> </modal-alert>
<modal-alert #createRoleModal [overflowBody]="false" (alertOutput)="createGroup()" classTitle="uk-background-primary uk-light" <modal-alert #createRoleModal [overflowBody]="false" (alertOutput)="createGroup()" classTitle="uk-background-primary uk-light"

View File

@ -23,6 +23,7 @@ import {NotificationHandler} from "../../../utils/notification-handler";
import {ClearCacheService} from "../../../services/clear-cache.service"; import {ClearCacheService} from "../../../services/clear-cache.service";
import {catchError, map, tap} from "rxjs/operators"; import {catchError, map, tap} from "rxjs/operators";
import {InputComponent} from "../../../sharedComponents/input/input.component"; import {InputComponent} from "../../../sharedComponents/input/input.component";
import {StakeholderUtils} from "../../../monitor-admin/utils/indicator-utils";
class InvitationResponse { class InvitationResponse {
email: string; email: string;
@ -43,7 +44,9 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@Input() @Input()
public id: string; public id: string;
@Input() @Input()
public type: string; set type(type: string) {
this._type = Role.mapType(type);
}
@Input() @Input()
public name: string; public name: string;
@Input() @Input()
@ -53,6 +56,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@Input() @Input()
public deleteAuthorizationLevel: 'curator' | 'manager' = 'curator'; public deleteAuthorizationLevel: 'curator' | 'manager' = 'curator';
@Input() @Input()
public inviteAuthorizationLevel: 'curator' | 'manager' = 'manager';
@Input()
public message: string = null; public message: string = null;
@Input() @Input()
public emailComposer: Function; public emailComposer: Function;
@ -86,12 +91,13 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
@ViewChild('deleteModal') deleteModal: AlertModal; @ViewChild('deleteModal') deleteModal: AlertModal;
@ViewChild('deletePendingModal') deletePendingModal: AlertModal; @ViewChild('deletePendingModal') deletePendingModal: AlertModal;
@ViewChild('createRoleModal') createRoleModal: AlertModal; @ViewChild('createRoleModal') createRoleModal: AlertModal;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
private _type: string;
constructor(private userRegistryService: UserRegistryService, constructor(private userRegistryService: UserRegistryService,
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private clearCacheService: ClearCacheService, private clearCacheService: ClearCacheService,
private notificationService: NotificationService, private notificationService: NotificationService,
private router: Router,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private fb: UntypedFormBuilder) { private fb: UntypedFormBuilder) {
} }
@ -140,7 +146,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
updateLists() { updateLists() {
this.loadActive = true; this.loadActive = true;
this.loadPending = true; this.loadPending = true;
this.subs.push(this.userRegistryService.getActive(this.type, this.id, this.role, true).subscribe(users => { this.subs.push(this.userRegistryService.getActive(this._type, this.id, this.role, true).subscribe(users => {
this.active = users; this.active = users;
this.filterActiveBySearch(this.filterForm.value.active); this.filterActiveBySearch(this.filterForm.value.active);
this.loadActive = false; this.loadActive = false;
@ -153,7 +159,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
} }
this.loadActive = false; this.loadActive = false;
})); }));
this.subs.push(this.userRegistryService.getPending(this.type, this.id, this.role, true).subscribe(users => { this.subs.push(this.userRegistryService.getPending(this._type, this.id, this.role, true).subscribe(users => {
this.pending = users; this.pending = users;
this.filterPendingBySearch(this.filterForm.value.pending); this.filterPendingBySearch(this.filterForm.value.pending);
this.loadPending = false; this.loadPending = false;
@ -182,7 +188,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
openDeleteModal(item: any) { openDeleteModal(item: any) {
if (this.showCurrent) { if (this.showCurrent) {
this.selectedUser = item.email; this.selectedUser = item.email;
this.deleteModal.alertTitle = 'Delete ' + this.role; this.deleteModal.alertTitle = 'Delete ' + this.stakeholderUtils.roles[this.role];
this.deleteModal.open(); this.deleteModal.open();
} else { } else {
this.selectedUser = item; this.selectedUser = item;
@ -192,7 +198,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
} }
openInviteModal() { openInviteModal() {
this.inviteModal.alertTitle = 'Invite ' + this.role; this.inviteModal.alertTitle = 'Invite ' + this.stakeholderUtils.roles[this.role];
this.inviteModal.okButtonLeft = false; this.inviteModal.okButtonLeft = false;
this.inviteModal.okButtonText = 'Send'; this.inviteModal.okButtonText = 'Send';
this.emailsForm = this.fb.array([], Validators.required); this.emailsForm = this.fb.array([], Validators.required);
@ -205,8 +211,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
this.createRoleModal.okButtonLeft = false; this.createRoleModal.okButtonLeft = false;
this.createRoleModal.okButtonText = 'Create'; this.createRoleModal.okButtonText = 'Create';
this.roleFb = this.fb.group({ this.roleFb = this.fb.group({
name: this.fb.control(Role.roleName(this.type, this.id), Validators.required), name: this.fb.control(Role.roleName(this._type, this.id), Validators.required),
description: this.fb.control(Role.roleName(this.type, this.id), Validators.required) description: this.fb.control(Role.roleName(this._type, this.id), Validators.required)
}); });
setTimeout(() => { setTimeout(() => {
this.roleFb.get('name').disable(); this.roleFb.get('name').disable();
@ -217,7 +223,7 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
deleteActive() { deleteActive() {
this.loadActive = true; this.loadActive = true;
this.subs.push(this.userRegistryService.remove(this.type, this.id, this.selectedUser, this.role).subscribe(() => { this.subs.push(this.userRegistryService.remove(this._type, this.id, this.selectedUser, this.role).subscribe(() => {
this.active = this.active.filter(user => user.email != this.selectedUser); this.active = this.active.filter(user => user.email != this.selectedUser);
if (this.currentActivePage.length === 0) { if (this.currentActivePage.length === 0) {
this.activePage = 1; this.activePage = 1;
@ -235,13 +241,13 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
deletePending() { deletePending() {
this.loadPending = true; this.loadPending = true;
this.subs.push(this.userRegistryService.cancelInvitation(this.type, this.id, this.selectedUser, this.role).subscribe(() => { this.subs.push(this.userRegistryService.cancelInvitation(this._type, this.id, this.selectedUser, this.role).subscribe(() => {
this.pending = this.pending.filter(user => user != this.selectedUser); this.pending = this.pending.filter(user => user != this.selectedUser);
this.filterPendingBySearch(this.filterForm.value.pending); this.filterPendingBySearch(this.filterForm.value.pending);
if (this.currentPendingPage.length === 0) { if (this.currentPendingPage.length === 0) {
this.pendingPage = 1; this.pendingPage = 1;
} }
NotificationHandler.rise(StringUtils.capitalize(this.role) + ' invitation to ' + this.selectedUser + ' has been <b>canceled</b>'); NotificationHandler.rise(StringUtils.capitalize(this.stakeholderUtils.roles[this.role]) + ' invitation to ' + this.selectedUser + ' has been <b>canceled</b>');
this.loadPending = false; this.loadPending = false;
}, error => { }, error => {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
@ -262,12 +268,12 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
let current = null; let current = null;
let invitations = (<Array<any>>this.emailsForm.value).map(email => { let invitations = (<Array<any>>this.emailsForm.value).map(email => {
current = email; current = email;
return this.userRegistryService.invite(this.type, this.id, { return this.userRegistryService.invite(this._type, this.id, {
link: this.link, link: this.link,
email: this.emailComposer(this.name, email, this.role) email: this.emailComposer(this.name, email, this.role)
}, this.role).pipe(map(invitation => new InvitationResponse(email, invitation), catchError(error => { }, this.role).pipe(catchError(error => {
return of(new InvitationResponse(current, null)); return of(null);
}))); }), map(invitation => new InvitationResponse(email, invitation)));
}); });
this.subs.push(forkJoin(invitations).subscribe(responses => { this.subs.push(forkJoin(invitations).subscribe(responses => {
let notifications = responses.map(response => { let notifications = responses.map(response => {
@ -289,7 +295,8 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
return of(null); return of(null);
} }
} else { } else {
NotificationHandler.rise('An error has occurred while sending the invitation mail to ' + response.email + '.Please try again later', 'danger'); NotificationHandler.rise('An error has occurred while sending the invitation mail to ' +
response.email + '.Check if the user is already a ' + this.stakeholderUtils.roles[this.role] + ' or try again later', 'danger');
return of(null); return of(null);
} }
}); });
@ -304,12 +311,12 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
createGroup() { createGroup() {
this.loadActive = true; this.loadActive = true;
this.loadPending = true; this.loadPending = true;
this.userRegistryService.createRole(this.type, this.id).subscribe(() => { this.userRegistryService.createRole(this._type, this.id).subscribe(() => {
NotificationHandler.rise('Group has been <b> successfully created</b>'); NotificationHandler.rise('Group has been <b> successfully created</b>');
this.updateLists(); this.updateLists();
}, error => { }, error => {
if(error.status === 409) { if(error.status === 409) {
NotificationHandler.rise('Group already exists. You can try to invite a ' + this.role + ' instead.', 'warning'); NotificationHandler.rise('Group already exists. You can try to invite a ' + this.stakeholderUtils.roles[this.role] + ' instead.', 'warning');
this.updateLists(); this.updateLists();
} else { } else {
NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); NotificationHandler.rise('An error has occurred. Please try again later', 'danger');
@ -322,17 +329,21 @@ export class RoleUsersComponent implements OnInit, OnDestroy, OnChanges {
public get canDelete() { public get canDelete() {
return (this.deleteAuthorizationLevel === 'curator'?this.isCurator:this.isManager); return (this.deleteAuthorizationLevel === 'curator'?this.isCurator:this.isManager);
} }
public get canInvite() {
return this.exists && (this.inviteAuthorizationLevel === 'curator'?this.isCurator:this.isManager);
}
public isMe(userId: string) { public isMe(userId: string) {
return userId && userId.includes(this.user.id) && !this.isCurator; return userId && userId.includes(this.user.id) && !this.isCurator;
} }
public get isManager(): boolean { public get isManager(): boolean {
return this.isCurator || !!Session.isManager(this.type, this.id, this.user); return this.isCurator || !!Session.isManager(this._type, this.id, this.user);
} }
public get isCurator(): boolean { public get isCurator(): boolean {
return this.isPortalAdmin || !!Session.isCurator(this.type, this.user); return this.isPortalAdmin || !!Session.isCurator(this._type, this.user);
} }
public get isPortalAdmin(): boolean { public get isPortalAdmin(): boolean {

View File

@ -141,8 +141,8 @@ export class SubscribersComponent implements OnInit, OnDestroy, OnChanges {
this.createRoleModal.okButtonLeft = false; this.createRoleModal.okButtonLeft = false;
this.createRoleModal.okButtonText = 'create'; this.createRoleModal.okButtonText = 'create';
this.roleFb = this.fb.group({ this.roleFb = this.fb.group({
name: this.fb.control(Role.mapType(this.type) + '.' + this.id, Validators.required), name: this.fb.control(Role.roleName(this.type, this.id), Validators.required),
description: this.fb.control(Role.mapType(this.type) + ' ' + this.id, Validators.required) description: this.fb.control(Role.roleName(this.type, this.id), Validators.required)
}); });
setTimeout(() => { setTimeout(() => {
this.roleFb.get('name').disable(); this.roleFb.get('name').disable();

View File

@ -5,7 +5,6 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import {PiwikServiceModule} from '../utils/piwik/piwikService.module';
import {HelperModule} from '../utils/helper/helper.module'; import {HelperModule} from '../utils/helper/helper.module';
import {Schema2jsonldModule} from '../sharedComponents/schema2jsonld/schema2jsonld.module'; import {Schema2jsonldModule} from '../sharedComponents/schema2jsonld/schema2jsonld.module';
import { SEOServiceModule } from '../sharedComponents/SEO/SEOService.module'; import { SEOServiceModule } from '../sharedComponents/SEO/SEOService.module';
@ -18,7 +17,6 @@ import {FullScreenModalModule} from '../utils/modal/full-screen-modal/full-scree
imports: [ imports: [
CommonModule, FormsModule, CommonModule, FormsModule,
RouterModule, RouterModule,
PiwikServiceModule,
HelperModule, HelperModule,
Schema2jsonldModule, SEOServiceModule, BreadcrumbsModule, SearchInputModule, Schema2jsonldModule, SEOServiceModule, BreadcrumbsModule, SearchInputModule,
FullScreenModalModule FullScreenModalModule

View File

@ -9,7 +9,6 @@ import {SearchResultsModule } from '../searchPages/searchUtils/searchResults.mod
import {DataProvidersServiceModule} from '../services/dataProvidersService.module'; import {DataProvidersServiceModule} from '../services/dataProvidersService.module';
import {SearchFormModule} from '../searchPages/searchUtils/searchForm.module'; import {SearchFormModule} from '../searchPages/searchUtils/searchForm.module';
import {IsRouteEnabled} from '../error/isRouteEnabled.guard';
import {SearchDataProvidersModule} from "../searchPages/searchDataProviders.module"; import {SearchDataProvidersModule} from "../searchPages/searchDataProviders.module";
import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
import {SearchInputModule} from "../sharedComponents/search-input/search-input.module"; import {SearchInputModule} from "../sharedComponents/search-input/search-input.module";
@ -25,7 +24,7 @@ import {SearchInputModule} from "../sharedComponents/search-input/search-input.m
declarations: [ declarations: [
SearchDataprovidersToDepositComponent SearchDataprovidersToDepositComponent
], ],
providers:[ IsRouteEnabled], providers:[],
exports: [ exports: [
SearchDataprovidersToDepositComponent SearchDataprovidersToDepositComponent
] ]

View File

@ -6,7 +6,9 @@ import {ConfigurationService} from '../utils/configuration/configuration.service
import {ConnectHelper} from '../connect/connectHelper'; import {ConnectHelper} from '../connect/connectHelper';
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
@Injectable() @Injectable({
providedIn: 'root'
})
export class IsRouteEnabled { export class IsRouteEnabled {
constructor(private router: Router, constructor(private router: Router,

View File

@ -32,7 +32,7 @@
</div> </div>
</div> </div>
<div class="uk-width-2-5@m uk-width-1-1@s uk-text-center" uk-scrollspy-class> <div class="uk-width-2-5@m uk-width-1-1@s uk-text-center" uk-scrollspy-class>
<img src="assets/common-assets/fos/fos-hero-img.svg" loading="lazy"> <img src="assets/common-assets/fos/fos-hero-img.svg" loading="lazy" alt="FoS logo">
</div> </div>
</div> </div>
</div> </div>

View File

@ -2,13 +2,11 @@ import {CommonModule} from "@angular/common";
import {NgModule} from "@angular/core"; import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms"; import {FormsModule} from "@angular/forms";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard";
import {IconsModule} from "../utils/icons/icons.module"; import {IconsModule} from "../utils/icons/icons.module";
import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module"; import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module";
import {SearchInputModule} from "../sharedComponents/search-input/search-input.module"; import {SearchInputModule} from "../sharedComponents/search-input/search-input.module";
import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module"; import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module";
import {PiwikService} from "../utils/piwik/piwik.service";
import {FosRoutingModule} from './fos-routing.module'; import {FosRoutingModule} from './fos-routing.module';
import {FosComponent} from './fos.component'; import {FosComponent} from './fos.component';
@ -22,9 +20,7 @@ import {FosComponent} from './fos.component';
declarations: [ declarations: [
FosComponent FosComponent
], ],
providers: [ providers: [],
PreviousRouteRecorder, PiwikService
],
exports: [ exports: [
FosComponent FosComponent
] ]

View File

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

View File

@ -36,10 +36,12 @@ import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.modu
import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-screen-modal.module'; import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-screen-modal.module';
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
import {DataProviderRoutingModule} from "./dataProvider-routing.module";
@NgModule({ @NgModule({
imports: imports:
[CommonModule, FormsModule, RouterModule, [CommonModule, FormsModule, RouterModule,
DataProviderRoutingModule,
IFrameModule, ErrorMessagesModule, LandingModule, IFrameModule, ErrorMessagesModule, LandingModule,
DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule, DataProvidersServiceModule, ProjectsServiceModule, SearchResearchResultsServiceModule,
PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule, PagingModule, Schema2jsonldModule, SEOServiceModule, ShowPublisherModule, HelperModule,

View File

@ -22,7 +22,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</ng-container> </ng-container>
<ng-container *ngIf="!inModal"> <ng-container *ngIf="!inModal">
<div *ngIf="properties.environment != 'production' && availableOn[0].fulltext" class="uk-flex uk-flex-middle" <div *ngIf="availableOn[0].fulltext" class="uk-flex uk-flex-middle"
[ngClass]="isMobile ? 'uk-width-1-1' : 'uk-text-bolder'"> [ngClass]="isMobile ? 'uk-width-1-1' : 'uk-text-bolder'">
<a [href]="availableOn[0].fulltext" target="_blank" <a [href]="availableOn[0].fulltext" target="_blank"
class="uk-flex uk-flex-middle uk-button-link" class="uk-flex uk-flex-middle uk-button-link"
@ -40,7 +40,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon> <icon [name]="availableOn[0].accessRightIcon" [flex]="true" [ratio]="(isMobile && usedBy == 'landing') ? 1 : 0.8"></icon>
</span> </span>
<ng-container *ngIf="!isMobile"> <ng-container *ngIf="!isMobile">
<a uk-tooltip="Source" target="_blank" <a target="_blank"
class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder"> class="uk-flex uk-flex-middle uk-flex-center uk-button-link uk-text-bolder">
<span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span> <span>{{sliceString(availableOn[0].downloadNames.join("; "), 20)}}</span>
<span> <span>
@ -108,7 +108,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</a> </a>
<ng-template #elseBlock> {{instance.license}}</ng-template> <ng-template #elseBlock> {{instance.license}}</ng-template>
</div> </div>
<div *ngIf="properties.environment != 'production' && instance.fulltext" class="uk-text-meta uk-text-truncate" uk-tooltip [title]="instance.fulltext"> <div *ngIf="instance.fulltext" class="uk-text-meta uk-text-truncate" uk-tooltip [title]="instance.fulltext">
Full-Text: Full-Text:
<a *ngIf="isUrl(instance.fulltext); else elseBlock" <a *ngIf="isUrl(instance.fulltext); else elseBlock"
[href]="instance.fulltext" target="_blank" class="custom-external uk-link-text"> [href]="instance.fulltext" target="_blank" class="custom-external uk-link-text">

View File

@ -89,7 +89,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</ng-container> </ng-container>
</span> </span>
<ng-container *ngIf="status"> <ng-container *ngIf="status">
<span>{{status}}</span> <span>{{status}} <ng-container *ngIf="currentDate <= endDate && currentDate >= startDate">(M{{calcCurrentMonth}})</ng-container></span>
</ng-container> </ng-container>
<ng-container *ngIf="date"> <ng-container *ngIf="date">
<span>{{date | date: 'dd MMM yyyy': 'UTC'}}</span> <span>{{date | date: 'dd MMM yyyy': 'UTC'}}</span>
@ -118,8 +118,9 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<showPublisher *ngIf="publisher || journal" [publisher]="publisher" [journal]="journal" <showPublisher *ngIf="publisher || journal" [publisher]="publisher" [journal]="journal"
[properties]="properties"></showPublisher> [properties]="properties"></showPublisher>
<!-- data provider labels --> <!-- data provider labels -->
<ng-container *ngIf="compatibility && !(compatibility.info == 'not available' && type == 'service')"> <span *ngIf="compatibility && !(compatibility.info == 'not available' && type == 'service')">
<span uk-tooltip title="Compatibility"> <span class="uk-text-meta uk-margin-xsmall-right">Compatibility:</span>
<span>
<a *ngIf="compatibility.id" <a *ngIf="compatibility.id"
[queryParams]="addEoscPrevInParams({datasourceId: compatibility.id})" routerLinkActive="router-link-active" [queryParams]="addEoscPrevInParams({datasourceId: compatibility.id})" routerLinkActive="router-link-active"
[routerLink]="properties.searchLinkToDataProvider.split('?')[0]"> [routerLink]="properties.searchLinkToDataProvider.split('?')[0]">
@ -137,10 +138,11 @@ import {RouterHelper} from "../../utils/routerHelper.class";
{{compatibility.name}} {{compatibility.name}}
</span> </span>
</span> </span>
</ng-container> </span>
<ng-container *ngIf="compatibilityString"> <span *ngIf="compatibilityString">
<span uk-tooltip title="Compatibility">{{compatibilityString}}</span> <span class="uk-text-meta uk-margin-xsmall-right">Compatibility:</span>
</ng-container> <span>{{compatibilityString}}</span>
</span>
<ng-container <ng-container
*ngIf="aggregationStatus && aggregationStatus.fulltexts && aggregationStatus.fulltexts > 0"> *ngIf="aggregationStatus && aggregationStatus.fulltexts && aggregationStatus.fulltexts > 0">
<span>OpenAIRE Text Mining</span> <span>OpenAIRE Text Mining</span>
@ -152,9 +154,9 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span>Publicly funded</span> <span>Publicly funded</span>
</ng-container> </ng-container>
<!-- Projects --> <!-- Projects -->
<span *ngIf="projects && projects.length > 0" <span *ngIf="projects && projects.length > 0">
[attr.uk-tooltip]="projects.length > projectsLimit ? 'cls: uk-invisible' : 'pos: top; cls: uk-active'" title="Funded by"> <span class="uk-text-meta uk-margin-xsmall-right">Funded by:</span>
{{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}} <span>{{showInline ? projectNames.join(', ') : projectNames.slice(0, projectsLimit).join(', ')}}</span>
<span *ngIf="projects.length > projectsLimit"> <span *ngIf="projects.length > projectsLimit">
<a *ngIf="!showInline" (click)="viewAllProjectsClick();" class="uk-background-muted custom-extra-entities"> <a *ngIf="!showInline" (click)="viewAllProjectsClick();" class="uk-background-muted custom-extra-entities">
+{{projects.length - projectsLimit | number}} projects +{{projects.length - projectsLimit | number}} projects
@ -166,9 +168,9 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</span> </span>
</span> </span>
<!-- Organizations --> <!-- Organizations -->
<span *ngIf="organizations && organizations.length > 0" <span *ngIf="organizations && organizations.length > 0">
[attr.uk-tooltip]="organizations.length > organizationsLimit ? 'cls: uk-invisible' : 'pos: top; cls: uk-active'" title="Partners"> <span class="uk-text-meta uk-margin-xsmall-right">Partners:</span>
{{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}} <span>{{showInline ? organizationNames.join(', ') : organizationNames.slice(0, organizationsLimit).join(', ')}}</span>
<span *ngIf="organizations.length > organizationsLimit"> <span *ngIf="organizations.length > organizationsLimit">
<a *ngIf="!showInline" (click)="viewAllPartnersClick();" class="uk-background-muted custom-extra-entities"> <a *ngIf="!showInline" (click)="viewAllPartnersClick();" class="uk-background-muted custom-extra-entities">
+{{organizations.length - organizationsLimit | number}} partners +{{organizations.length - organizationsLimit | number}} partners
@ -180,9 +182,10 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</span> </span>
</span> </span>
<!-- Subjects --> <!-- Subjects -->
<span uk-tooltip="Subjects" *ngIf="subjects && subjects.length > 0" [class.truncated]="subjects.length > 3"> <span *ngIf="subjects && subjects.length > 0" [class.truncated]="subjects.length > 3">
{{subjects.slice(0, 3).join(', ')}} {{subjects.slice(0, 3).join(', ')}}
</span> </span>
<!-- For tabs in landing -->
<ng-container *ngIf="provenanceAction"> <ng-container *ngIf="provenanceAction">
<span>{{provenanceAction}}</span> <span>{{provenanceAction}}</span>
</ng-container> </ng-container>
@ -292,7 +295,7 @@ export class EntityMetadataComponent {
return this.projects.map(project => { return this.projects.map(project => {
let value = project.funderShortname ? project.funderShortname : project.funderName; let value = project.funderShortname ? project.funderShortname : project.funderName;
if (project.acronym || project.title) { 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)); (project.title.length > 25 ? (project.title.slice(0, 25) + '...'): project.title));
} }
// if(project.code) { // if(project.code) {
@ -361,4 +364,18 @@ export class EntityMetadataComponent {
this.projectsModal.open(); 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;
}
} }

View File

@ -20,14 +20,16 @@ import {RouterHelper} from "../../utils/routerHelper.class";
</div> </div>
<div *ngIf="!isMobile"> <div *ngIf="!isMobile">
<span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index"> <span *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index">
<span class="uk-text-emphasis"> <span class="uk-text-emphasis" (click)="dropClicked=true">
<a class="uk-link uk-link-text"> <a class="uk-link uk-link-text">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container> <ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</a> </a>
</span> </span>
<div class="default-dropdown uk-margin-remove-top uk-dropdown" <div class="default-dropdown uk-margin-remove-top uk-dropdown"
uk-dropdown="pos: bottom-left; mode:click"> uk-dropdown="pos: bottom-left; mode:click">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container> <ng-container *ngIf="dropClicked">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item, index: i}"></ng-container>
</ng-container>
</div> </div>
<span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span> <span *ngIf="i < (fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold).length - 1)">, </span>
</span> </span>
@ -35,13 +37,13 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<div *ngIf="isMobile"> <div *ngIf="isMobile">
<div *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index" <div *ngFor="let item of fundedByProjects.slice(0, viewAll?fundedByProjects.length:threshold) let i=index"
class="uk-flex uk-flex-middle uk-margin-small-bottom"> class="uk-flex uk-flex-middle uk-margin-small-bottom">
<span class="uk-text-emphasis uk-width-expand"> <span class="uk-text-emphasis uk-width-expand" (click)="dropClicked=true">
<ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container> <ng-container *ngTemplateOutlet="funder; context: {item: item}"></ng-container>
</span> </span>
<a #toggle><icon name="info" visuallyHidden="info" [type]="'outlined'"></icon></a> <a #toggle><icon name="info" visuallyHidden="info" [type]="'outlined'"></icon></a>
<mobile-dropdown [toggle]="toggle"> <mobile-dropdown [toggle]="toggle">
<div class="uk-margin-remove-top"> <div *ngIf="dropClicked" class="uk-margin-remove-top">
<ng-container *ngTemplateOutlet="dropInfo; context: { item: item}"></ng-container> <ng-container *ngTemplateOutlet="dropInfo; context: { item: item, index: i}"></ng-container>
</div> </div>
</mobile-dropdown> </mobile-dropdown>
</div> </div>
@ -54,7 +56,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span *ngIf="item['acronym'] || item['title']">| {{ item['acronym'] ? item['acronym'] : item['title']}}</span> <span *ngIf="item['acronym'] || item['title']">| {{ item['acronym'] ? item['acronym'] : item['title']}}</span>
</ng-template> </ng-template>
<ng-template #dropInfo let-item=item> <ng-template #dropInfo let-item=item let-index=index>
<div class="uk-padding-small"> <div class="uk-padding-small">
<span>Project</span> <span>Project</span>
<div class="uk-margin-bottom"> <div class="uk-margin-bottom">
@ -84,7 +86,7 @@ import {RouterHelper} from "../../utils/routerHelper.class";
<span class="uk-text-meta">Funding stream: </span>{{item.funding}} <span class="uk-text-meta">Funding stream: </span>{{item.funding}}
</li> </li>
</ul> </ul>
<div *ngIf="getVocabularyLabel(item, provenanceActionVocabulary, i) || item.validated" class="uk-text-meta"> <div *ngIf="item.provenanceAction || item.validated" class="uk-text-meta">
<span *ngIf="item.validated">Validated by funder</span> <span *ngIf="item.validated">Validated by funder</span>
<span *ngIf="item.provenanceAction && item.validated"> | </span> <span *ngIf="item.provenanceAction && item.validated"> | </span>
<span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span> <span *ngIf="item.provenanceAction">{{item.provenanceAction}}</span>
@ -105,8 +107,15 @@ export class FundedByComponent {
public url = properties.searchLinkToProject.split('?')[0]; public url = properties.searchLinkToProject.split('?')[0];
public title: string = "Funded by"; public title: string = "Funded by";
@Input() provenanceActionVocabulary = null; @Input() provenanceActionVocabulary = null;
public provenancesCalculated: boolean[] = []; // public provenancesCalculated: boolean[] = [];
public routerHelper:RouterHelper = new RouterHelper(); public routerHelper:RouterHelper = new RouterHelper();
public dropClicked: boolean = false;
public ngOnInit() {
this.fundedByProjects.forEach((project, index) => {
this.getVocabularyLabel(project, this.provenanceActionVocabulary, index);
})
}
public viewAllClick() { public viewAllClick() {
if(this.fundedByProjects.length <= this.threshold*2) { if(this.fundedByProjects.length <= this.threshold*2) {
@ -124,11 +133,11 @@ export class FundedByComponent {
} }
public getVocabularyLabel(item: any, vocabulary: any, index: number) { public getVocabularyLabel(item: any, vocabulary: any, index: number) {
if(!this.provenancesCalculated[index]) { // if(!this.provenancesCalculated[index]) {
this.provenancesCalculated[index] = true; // this.provenancesCalculated[index] = true;
item.provenanceAction = HelperFunctions.getVocabularyLabel(item.provenanceAction, vocabulary, false); item.provenanceAction = HelperFunctions.getVocabularyLabel(item.provenanceAction, vocabulary, false);
} // }
return item.provenanceAction; // return item.provenanceAction;
} }
public addEoscPrevInParams(obj) { public addEoscPrevInParams(obj) {

View File

@ -5,24 +5,19 @@ import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
import {TabPagingComponent} from './tabPaging.component';
import {ShowTitleComponent} from './showTitle.component'; import {ShowTitleComponent} from './showTitle.component';
import {AddThisComponent} from './addThis.component'; import {AddThisComponent} from './addThis.component';
import {PiwikServiceModule} from '../../utils/piwik/piwikService.module';
import {PreviousRouteRecorder} from'../../utils/piwik/previousRouteRecorder.guard';
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, RouterModule, PiwikServiceModule CommonModule, FormsModule, RouterModule
], ],
declarations: [ declarations: [
TabPagingComponent, ShowTitleComponent, AddThisComponent ShowTitleComponent, AddThisComponent
], ],
providers:[ providers:[],
PreviousRouteRecorder
],
exports: [ exports: [
TabPagingComponent, ShowTitleComponent, AddThisComponent ShowTitleComponent, AddThisComponent
] ]
}) })
export class LandingModule { } export class LandingModule { }

View File

@ -42,7 +42,7 @@ export class ParsingFunctions {
"funderShortname": "", "funderName": "", "funderShortname": "", "funderName": "",
"funding": "", "code": "", "provenanceAction": "", "validated": false "funding": "", "code": "", "provenanceAction": "", "validated": false
}; };
if (relation.title != 'unidentified') { if (relation.title != 'unidentified') {
fundedByProject['id'] = relation['to'].content; fundedByProject['id'] = relation['to'].content;
fundedByProject['acronym'] = relation.acronym; fundedByProject['acronym'] = relation.acronym;
@ -538,7 +538,8 @@ export class ParsingFunctions {
if (pid.hasOwnProperty("classid") && pid['classid'] != "") { if (pid.hasOwnProperty("classid") && pid['classid'] != "") {
if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data" if (pid.classid == "doi" || pid.classid == "pmc" || pid.classid == "handle" || pid.classid == "pmid" || pid.classid == "re3data"
|| pid.classid == "swhid") { || pid.classid == "swhid"
|| pid.classid == "ROR" || pid.classid == "ISNI" || pid.classid == "Wikidata" || pid.classid == "FundRef") {
if (!identifiers.has(pid.classid)) { if (!identifiers.has(pid.classid)) {
identifiers.set(pid.classid, new Array<string>()); identifiers.set(pid.classid, new Array<string>());
} }
@ -547,7 +548,8 @@ export class ParsingFunctions {
} else { } else {
for (let i = 0; i < pid.length; i++) { for (let i = 0; i < pid.length; i++) {
if (pid[i].classid == "doi" || pid[i].classid == "pmc" || pid[i].classid == "handle" || pid[i].classid == "pmid" || pid[i].classid == "re3data" if (pid[i].classid == "doi" || pid[i].classid == "pmc" || pid[i].classid == "handle" || pid[i].classid == "pmid" || pid[i].classid == "re3data"
|| pid[i].classid == "swhid") { || 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)) { if (!identifiers.has(pid[i].classid)) {
identifiers.set(pid[i].classid, new Array<string>()); identifiers.set(pid[i].classid, new Array<string>());
} }
@ -579,7 +581,7 @@ export class ParsingFunctions {
return eoscSubjectsFound; return eoscSubjectsFound;
} }
// publication & dataset landing : for subjects and otherSubjects and classifiedSubjects // publication & dataset landing : for subjects and otherSubjects and classifiedSubjects
parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map<string, string[]>, Map<string, string[]>, string[], string[],] { parseAllSubjects(_subjects: any, vocabulary: any): [string[], Map<string, string[]>, Map<string, string[]>, string[], string[],] {
// let eoscSubjectsFound = []; // let eoscSubjectsFound = [];
@ -588,12 +590,12 @@ export class ParsingFunctions {
let classifiedSubjects: Map<string, string[]>; let classifiedSubjects: Map<string, string[]>;
let fos: string[]; let fos: string[];
let sdg: string[]; let sdg: string[];
let setOfEoscSubjects: Set<string> = new Set(); let setOfEoscSubjects: Set<string> = new Set();
let subject; let subject;
let length = Array.isArray(_subjects) ? _subjects.length : 1; let length = Array.isArray(_subjects) ? _subjects.length : 1;
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
subject = Array.isArray(_subjects) ? _subjects[i] : _subjects; subject = Array.isArray(_subjects) ? _subjects[i] : _subjects;
if (subject.classid != "") { if (subject.classid != "") {
@ -626,7 +628,7 @@ export class ParsingFunctions {
if (classifiedSubjects == undefined) { if (classifiedSubjects == undefined) {
classifiedSubjects = new Map<string, string[]>(); classifiedSubjects = new Map<string, string[]>();
} }
let content: string = subject.content + ""; let content: string = subject.content + "";
// let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content); // let checkAndAddEoscSubjectResp = this.checkAndAddEoscSubject(setOfEoscSubjects, eoscSubjectsFound, subject, content);
// let found: boolean = checkAndAddEoscSubjectResp["found"]; // let found: boolean = checkAndAddEoscSubjectResp["found"];
@ -637,7 +639,11 @@ export class ParsingFunctions {
if (!classifiedSubjects.has(subject.classname)) { if (!classifiedSubjects.has(subject.classname)) {
classifiedSubjects.set(subject.classname, new Array<string>()); classifiedSubjects.set(subject.classname, new Array<string>());
} }
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 { } 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]; return [subjects, otherSubjects, classifiedSubjects, fos, sdg];
} }

View File

@ -15,34 +15,36 @@ import {StringUtils} from "../../../utils/string-utils.class";
template: ` template: `
<modal-alert #selectionModal [large]="true" (alertOutput)="modalOutput()" (cancelOutput)="modalCancel()" <modal-alert #selectionModal [large]="true" (alertOutput)="modalOutput()" (cancelOutput)="modalCancel()"
[okDisabled]="!sent && !selectionStep1 && (form.invalid || sending)"> [okDisabled]="!sent && !selectionStep1 && (form.invalid || sending)">
<sdg-selection *ngIf="subjects && subjectType == 'sdg'" #selection [class.uk-hidden]="!selectionStep1" <ng-container *ngIf="isOpen">
[subjects]="subjects" [entityType]="entityType"></sdg-selection> <sdg-selection *ngIf="subjects && subjectType == 'sdg'" #selection [class.uk-hidden]="!selectionStep1"
<fos-selection *ngIf="subjects && subjectType == 'fos'" #selection [class.uk-hidden]="!selectionStep1" [subjects]="subjects" [entityType]="entityType"></sdg-selection>
[subjects]="subjects" [contentHeight]="selectionModal.bodyHeight" [inModal]="true"></fos-selection> <fos-selection *ngIf="subjects && subjectType == 'fos'" #selection [class.uk-hidden]="!selectionStep1"
<div [class.uk-hidden]="selectionStep1"> [subjects]="subjects" [contentHeight]="selectionModal.bodyHeight" [inModal]="true"></fos-selection>
<div class="uk-flex uk-flex-column uk-flex-middle"> <div [class.uk-hidden]="selectionStep1">
<ng-container *ngIf="!sent && !error"> <div class="uk-flex uk-flex-column uk-flex-middle">
<div>Thank you for your feedback.</div> <ng-container *ngIf="!sent && !error">
<div>Before sending us your options, would you like to leave us your e-mail to notify you about the reporting status?</div> <div>Thank you for your feedback.</div>
<div input class="uk-width-1-2 uk-margin-medium-top uk-margin-medium-bottom" <div>Before sending us your options, would you like to leave us your e-mail to notify you about the reporting status?</div>
[formInput]="form.get('email')" placeholder="E-mail"> <div input class="uk-width-1-2 uk-margin-medium-top uk-margin-medium-bottom"
<span note>(Optional)</span> [formInput]="form.get('email')" placeholder="E-mail">
<span note>(Optional)</span>
</div>
<div>
<re-captcha (resolved)="handleRecaptcha($event)" [siteKey]="properties.reCaptchaSiteKey"
[ngClass]="sending ? 'uk-hidden':''"></re-captcha>
<loading [ngClass]="sending ? '':'uk-hidden'"></loading>
</div>
</ng-container>
<ng-container *ngIf="sent">
<p>Your feedback is successfully received and it will soon be reviewed by our graph experts!</p>
<icon customClass="uk-text-background" name="check" [ratio]="4"></icon>
</ng-container>
<div *ngIf="error" class="uk-alert uk-alert-danger uk-text-center uk-width-large ng-star-inserted"
role="alert">Email sent failed! Please try again.
</div> </div>
<div>
<re-captcha (resolved)="handleRecaptcha($event)" [siteKey]="properties.reCaptchaSiteKey"
[ngClass]="sending ? 'uk-hidden':''"></re-captcha>
<loading [ngClass]="sending ? '':'uk-hidden'"></loading>
</div>
</ng-container>
<ng-container *ngIf="sent">
<p>Your feedback is successfully received and it will soon be reviewed by our graph experts!</p>
<icon customClass="uk-text-background" name="check" [ratio]="4"></icon>
</ng-container>
<div *ngIf="error" class="uk-alert uk-alert-danger uk-text-center uk-width-large ng-star-inserted"
role="alert">Email sent failed! Please try again.
</div> </div>
</div> </div>
</div> </ng-container>
</modal-alert> </modal-alert>
` `
}) })
@ -62,6 +64,7 @@ export class SdgFosSuggestComponent {
public sent: boolean = false; public sent: boolean = false;
public error: boolean = false; public error: boolean = false;
subscriptions: Subscription[] = []; subscriptions: Subscription[] = [];
isOpen: boolean = false;
constructor(private emailService: EmailService, private fb: FormBuilder, private cdr: ChangeDetectorRef) {} constructor(private emailService: EmailService, private fb: FormBuilder, private cdr: ChangeDetectorRef) {}

View File

@ -26,8 +26,9 @@ import {properties} from "../../../../environments/environment";
<span class="uk-text-meta uk-text-small" [class.uk-text-uppercase]="key != 're3data'">{{key}}: </span> <span class="uk-text-meta uk-text-small" [class.uk-text-uppercase]="key != 're3data'">{{key}}: </span>
<span [class.uk-margin-small-left]="modal"> <span [class.uk-margin-small-left]="modal">
<ng-container *ngFor="let item of identifiers.get(key) let j=index"> <ng-container *ngFor="let item of identifiers.get(key) let j=index">
<a *ngIf="key == 'doi' || key == 'pmc' || key == 'pmid' || key == 'handle' || key == 're3data' || key == 'swhid'" <a *ngIf="key == 'doi' || key == 'pmc' || key == 'pmid' || key == 'handle' || key == 're3data' || key == 'swhid'
[href]="getUrl(key) + item" target="_blank" class="uk-display-inline-block custom-external"> || key == 'ROR' || key == 'ISNI' || key == 'Wikidata' || key == 'FundRef'"
[href]="getUrl(key, item) + item" target="_blank" class="uk-display-inline-block custom-external">
{{item}} {{item}}
</a> </a>
<ng-container *ngIf="(j !== (identifiers.get(key).length - 1))">, </ng-container> <ng-container *ngIf="(j !== (identifiers.get(key).length - 1))">, </ng-container>
@ -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") { if(key == "doi") {
return properties.doiURL; return properties.doiURL;
} else if(key == "pmc") { } else if(key == "pmc") {
@ -126,6 +130,14 @@ export class ShowIdentifiersComponent implements AfterViewInit {
return properties.r3DataURL; return properties.r3DataURL;
} else if(key == "swhid") { } else if(key == "swhid") {
return properties.swhURL; 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;
} }
} }

View File

@ -5,7 +5,8 @@ import {EnvProperties} from "../../utils/properties/env-properties";
selector: 'showPublisher, [showPublisher]', selector: 'showPublisher, [showPublisher]',
template: ` template: `
<ng-container *ngIf="publisher"> <ng-container *ngIf="publisher">
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Publisher'">{{publisher}}</span> <span class="uk-text-meta uk-margin-xsmall-right">Publisher:</span>
<span>{{publisher}}</span>
<span *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn'] <span *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])" || journal['volume'] || journal['eissn'] || journal['issue'])"
class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span> class="uk-margin-xsmall-left uk-margin-xsmall-right bullet"></span>
@ -14,7 +15,8 @@ import {EnvProperties} from "../../utils/properties/env-properties";
|| journal['volume'] || journal['eissn'] || journal['issue'])"> || journal['volume'] || journal['eissn'] || journal['issue'])">
<ng-container *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn'] <ng-container *ngIf="journal && (journal['journal'] || journal['issn'] || journal['lissn']
|| journal['volume'] || journal['eissn'] || journal['issue'])"> || journal['volume'] || journal['eissn'] || journal['issue'])">
<span [attr.uk-tooltip]="'cls: uk-active'" [title]="'Journal'"> <span>
<span class="uk-text-meta uk-margin-xsmall-right">Journal:</span>
<span *ngIf="journal['journal']">{{journal['journal']}}</span> <span *ngIf="journal['journal']">{{journal['journal']}}</span>
<span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span> <span *ngIf="journal['journal'] && (journal['volume'] || journal['issue'])">, </span>
<ng-container *ngIf="journal['volume']"> <ng-container *ngIf="journal['volume']">

View File

@ -1,24 +0,0 @@
import {Component, Input, Output, EventEmitter} from '@angular/core';
@Component({
selector: 'tabPaging',
template: `
<div class="uk-panel" *ngIf="!showAll && length > 10">
<a (click)="changeShowAll.emit({value: true});">
<div class="uk-float-right">view all {{length | number}}</div>
</a>
</div>
`
})
export class TabPagingComponent {
@Input() showAll: boolean;
@Input() length: number;
@Output() changeShowAll: EventEmitter<any> = new EventEmitter();
constructor () {
}
ngOnInit() {
}
}

View File

@ -18,7 +18,7 @@ import {ResultPreviewModule} from "../../../utils/result-preview/result-preview.
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, ResultLandingUtilsModule, CommonModule, FormsModule, ResultLandingUtilsModule,
PagingModule, ErrorMessagesModule, ShowAuthorsModule, LandingModule, NoLoadPaging, ResultPreviewModule PagingModule, ErrorMessagesModule, ShowAuthorsModule, NoLoadPaging, ResultPreviewModule
], ],
declarations: [ declarations: [
OrganizationsDeletedByInferenceComponent OrganizationsDeletedByInferenceComponent

View File

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

View File

@ -19,57 +19,28 @@
</div> </div>
</div> </div>
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid> <div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left column -->
<!-- <div id="landing-left-sidebar" *ngIf="organizationInfo" class="uk-visible@s uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-column uk-flex-right uk-sticky"
uk-sticky="end: true" [attr.offset]="offset">
<div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list">
<li class="uk-text-center">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
</span>
</a>
</li>
<li class="uk-text-center"
[title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a class="uk-link-text uk-text-bold uk-text-uppercase" (click)="buildFunderOptions(); openDownloadReportsModal()">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="download" visuallyHidden="download"></icon>
</span>
</a>
</li>
</ul>
</div>
</div>
</div> -->
<!-- center/right column --> <!-- center/right column -->
<div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default"> <div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default">
<!-- Graph and feedback --> <!-- Graph and feedback -->
<ng-template #graph_and_feedback_template> <ng-template #graph_and_feedback_template>
<div class="uk-padding-xsmall"> <div class="uk-padding-xsmall">
<div class="uk-container uk-container-xlarge uk-flex uk-flex-between uk-flex-wrap uk-margin-small-top uk-margin-small-bottom" [class.uk-invisible]="!organizationInfo"> <div class="uk-container uk-container-xlarge uk-flex uk-flex-between uk-flex-wrap uk-margin-small-top uk-margin-small-bottom" [class.uk-invisible]="!organizationInfo">
<!-- Last Index Info--> <!-- Last Index Info-->
<a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l"> <a href="https://graph.openaire.eu" target="_blank" class="uk-width-1-1 uk-width-auto@l">
<img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;"> <img src="assets/common-assets/openaire-badge-1.png" alt="Powered by OpenAIRE graph" style="height: 15px;">
</a> </a>
<span *ngIf="indexUpdateDate" class="uk-text-baseline uk-text-meta uk-width-1-1 uk-width-auto@l"> <span *ngIf="indexUpdateDate" class="uk-text-baseline uk-text-meta uk-width-1-1 uk-width-auto@l">
Last update of records in OpenAIRE: {{indexUpdateDate | date: 'MMM dd, yyyy'}} Last update of records in OpenAIRE: {{indexUpdateDate | date: 'MMM dd, yyyy'}}
</span> </span>
<!--Feedback--> <!--Feedback-->
<div *ngIf="properties.reCaptchaSiteKey" class="uk-width-1-1 uk-width-auto@l"> <div *ngIf="properties.reCaptchaSiteKey" class="uk-width-1-1 uk-width-auto@l">
<span class="uk-text-meta uk-text-xsmall">Found an issue? </span> <span class="uk-text-meta uk-text-xsmall">Found an issue? </span>
<a (click)="showFeedback = true; scroll()" class="uk-text-xsmall">Give us feedback</a> <a (click)="showFeedback = true; scroll()" class="uk-text-xsmall">Give us feedback</a>
</div> </div>
</div> </div>
</div> </div>
</ng-template> </ng-template>
<div #graph_and_feedback id="graph_and_feedback" class="uk-blur-background uk-text-xsmall uk-visible@m" <div #graph_and_feedback id="graph_and_feedback" class="uk-blur-background uk-text-xsmall uk-visible@m"
@ -123,35 +94,10 @@
<!-- Main content --> <!-- Main content -->
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')"> <div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<!-- Actions for mobile viewport -->
<div class="uk-flex uk-flex-right uk-margin-medium-bottom uk-hidden@s">
<div class="uk-margin-small-right">
<a (click)="openAddThisModal()" [title]="'Share this '+openaireEntities.ORGANIZATION+' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
</span>
</a>
</div>
<div [title]="'Download reports'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a class="uk-link-text uk-text-bold uk-text-uppercase" (click)="buildFunderOptions(); openDownloadReportsModal()">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="download" visuallyHidden="download"></icon>
</span>
</a>
</div>
</div>
<!-- Helper --> <!-- Helper -->
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0" <helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper> [texts]="pageContents['top']"></helper>
<!-- Versions -->
<!-- <span *ngIf="organizationInfo.deletedByInferenceIds" class="uk-text-primary uk-flex uk-flex-middle">
<icon flex="true" ratio="0.8" name="auto_awesome_motion"></icon>
<a (click)="openDeletedByInference()" class="uk-text-primary uk-text-small uk-margin-small-left">
View all {{organizationInfo.deletedByInferenceIds.length}} versions
</a>
</span> -->
<!-- Landing header --> <!-- Landing header -->
<landing-header [properties]="properties" [title]="organizationInfo.title.name" <landing-header [properties]="properties" [title]="organizationInfo.title.name"
[subTitle]="(organizationInfo.name [subTitle]="(organizationInfo.name
@ -171,6 +117,10 @@
<div *ngIf="organizationInfo.country && !organizationInfo.country.toLowerCase().includes('unknown')"> <div *ngIf="organizationInfo.country && !organizationInfo.country.toLowerCase().includes('unknown')">
<span class="uk-text-meta">Country: </span>{{organizationInfo.country}} <span class="uk-text-meta">Country: </span>{{organizationInfo.country}}
</div> </div>
<!-- Identifiers -->
<div *ngIf="organizationInfo.identifiers && organizationInfo.identifiers.size > 0" class="uk-margin-small-top">
<showIdentifiers [identifiers]="organizationInfo.identifiers" [showViewAll]="true"></showIdentifiers>
</div>
</div> </div>
</div> </div>
<!-- Tabs section --> <!-- Tabs section -->
@ -257,9 +207,7 @@
</search-tab> </search-tab>
</div> </div>
</div> </div>
<div class="uk-text-xsmall uk-hidden@m">
<ng-container *ngTemplateOutlet="graph_and_feedback_template"></ng-container>
</div>
<!-- Helper --> <!-- Helper -->
<helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0" <helper *ngIf="pageContents && pageContents['bottom'] && pageContents['bottom'].length > 0"
[texts]="pageContents['bottom']"> [texts]="pageContents['bottom']">
@ -270,12 +218,12 @@
</div> </div>
</div> </div>
</div> </div>
<!-- Feedback -->
<feedback *ngIf="showFeedback && organizationInfo && properties.reCaptchaSiteKey" [organizationInfo]="organizationInfo"
[properties]="properties" [entityType]="'organization'" [fields]="feedbackFields"
[(showForm)]="showFeedback">
</feedback>
</div> </div>
<!-- Feedback -->
<feedback *ngIf="organizationInfo && properties.reCaptchaSiteKey" [organizationInfo]="organizationInfo"
[properties]="properties" [entityType]="'organization'" [fields]="feedbackFields"
[(showForm)]="showFeedback">
</feedback>
</div> </div>
<!-- Mobile view --> <!-- Mobile view -->
@ -287,6 +235,23 @@
&& organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null" && organizationInfo.title.name !== organizationInfo.name)?organizationInfo.name:null"
[entityType]="'organization'" [prevPath]="prevPath"> [entityType]="'organization'" [prevPath]="prevPath">
</landing-header> </landing-header>
<div class="uk-text-small">
<!-- Web Page -->
<div *ngIf="organizationInfo.title && organizationInfo.title.url" class="uk-margin-small-bottom uk-display-inline-block">
<span class="uk-text-meta">Web page: </span>
<a [href]="organizationInfo.title.url" target="_blank" class="uk-button uk-button-text uk-text-lowercase uk-text-normal custom-external">
{{organizationInfo.title.url}}
</a>
</div>
<!-- Country -->
<div *ngIf="organizationInfo.country && !organizationInfo.country.toLowerCase().includes('unknown')">
<span class="uk-text-meta">Country: </span>{{organizationInfo.country}}
</div>
<!-- Identifiers -->
<div *ngIf="organizationInfo.identifiers && organizationInfo.identifiers.size > 0" class="uk-margin-small-top">
<showIdentifiers [identifiers]="organizationInfo.identifiers" [showViewAll]="true" [isMobile]="true"></showIdentifiers>
</div>
</div>
<div class="uk-section uk-margin-top uk-text-large uk-text-empashis uk-text-bold"> <div class="uk-section uk-margin-top uk-text-large uk-text-empashis uk-text-bold">
<hr> <hr>
<ng-container> <ng-container>
@ -406,10 +371,7 @@
[type]="'organizations'" [prevPath]="prevPath"> [type]="'organizations'" [prevPath]="prevPath">
</organizationsDeletedByInference> </organizationsDeletedByInference>
</modal-alert> </modal-alert>
<!-- Share -->
<modal-alert *ngIf="organizationInfo" #addThisModal classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis>
</modal-alert>
<!-- Download --> <!-- Download -->
<modal-alert *ngIf="organizationInfo" #downloadReportsModal large="true"> <modal-alert *ngIf="organizationInfo" #downloadReportsModal large="true">
<div class="uk-padding-small uk-margin-small-left uk-margin-small-right"> <div class="uk-padding-small uk-margin-small-left uk-margin-small-right">

View File

@ -77,7 +77,6 @@ export class OrganizationComponent {
@ViewChild('downloadReportsFsModal') downloadReportsFsModal: FullScreenModalComponent; @ViewChild('downloadReportsFsModal') downloadReportsFsModal: FullScreenModalComponent;
// @ViewChild('downloadReportModal') downloadReportModal; // @ViewChild('downloadReportModal') downloadReportModal;
// @ViewChild('downloadFunderReportModal') downloadFunderReportModal; // @ViewChild('downloadFunderReportModal') downloadFunderReportModal;
@ViewChild('addThisModal') addThisModal;
@ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent; @ViewChild('addThisFsModal') addThisFsModal: FullScreenModalComponent;
@ViewChild(ModalLoading) loading: ModalLoading; @ViewChild(ModalLoading) loading: ModalLoading;
@ -717,13 +716,6 @@ export class OrganizationComponent {
this.downloadReportsModal.cancel(); 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 = "") { public getParamsForSearchLink(type: string = "") {
if(type) { if(type) {
return this.routerHelper.createQueryParams(['f0', 'fv0', 'type', 'qf', 'sortBy'], ['relorganizationid', this.organizationId, type, 'false', 'resultdateofacceptance,descending']); return this.routerHelper.createQueryParams(['f0', 'fv0', 'type', 'qf', 'sortBy'], ['relorganizationid', this.organizationId, type, 'false', 'resultdateofacceptance,descending']);

View File

@ -33,11 +33,14 @@ import {graph, versions} from "../../utils/icons/icons";
import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module"; import {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module"; import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module";
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
import {OrganizationRoutingModule} from "./organization-routing.module";
import {ResultLandingUtilsModule} from "../landing-utils/resultLandingUtils.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, RouterModule, CommonModule, FormsModule, RouterModule,
OrganizationRoutingModule,
LoadingModalModule, AlertModalModule, ErrorMessagesModule, LoadingModalModule, AlertModalModule, ErrorMessagesModule,
LandingModule, LandingModule,
DataProvidersServiceModule, DataProvidersServiceModule,
@ -49,7 +52,7 @@ import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.mod
ProjectsServiceModule, ProjectsServiceModule,
Schema2jsonldModule, SEOServiceModule, HelperModule, Schema2jsonldModule, SEOServiceModule, HelperModule,
OrganizationsDeletedByInferenceModule, LandingHeaderModule, FeedbackModule, OrganizationsDeletedByInferenceModule, LandingHeaderModule, FeedbackModule,
TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule, FullScreenModalModule, EGIDataTransferModule, EntityActionsModule TabsModule, SearchTabModule, LoadingModule, IconsModule, InputModule, FullScreenModalModule, EntityActionsModule, ResultLandingUtilsModule
], ],
declarations: [ declarations: [
OrganizationComponent, OrganizationComponent,

View File

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

View File

@ -32,9 +32,11 @@ import {FullScreenModalModule} from '../../utils/modal/full-screen-modal/full-sc
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module"; import {EGIDataTransferModule} from "../../utils/dataTransfer/transferData.module";
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module"; import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.module";
import {ProjectRoutingModule} from "./project-routing.module";
@NgModule({ @NgModule({
imports: [ imports: [
ProjectRoutingModule,
CommonModule, FormsModule, RouterModule, LandingModule, CommonModule, FormsModule, RouterModule, LandingModule,
LoadingModalModule, AlertModalModule, ErrorMessagesModule, LoadingModalModule, AlertModalModule, ErrorMessagesModule,
IFrameModule, ReportsServiceModule, IFrameModule, ReportsServiceModule,

View File

@ -27,8 +27,8 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
<ul class="uk-list uk-margin"> <ul class="uk-list uk-margin">
<li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)"> <li *ngFor="let result of results.slice((page-1)*pageSize, page*pageSize)">
<result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)" <result-preview [modal]="modal" [properties]="properties" [hasLink]="false" [result]="getResultPreview(result)"
[showOrcid]="false" [isCard]="false" [prevPath]="prevPath" [showInline]="true" [showOrcid]="false" [prevPath]="prevPath" [showInline]="true"
[isDeletedByInferenceModal]="true"></result-preview> [isDeletedByInferenceModal]="true" [isMobile]="isMobile"></result-preview>
</li> </li>
</ul> </ul>
<no-load-paging *ngIf="results.length > pageSize" [type]="type" <no-load-paging *ngIf="results.length > pageSize" [type]="type"
@ -40,6 +40,7 @@ import {HelperFunctions} from "../../../utils/HelperFunctions.class";
` `
}) })
export class DeletedByInferenceComponent { export class DeletedByInferenceComponent {
@Input() isMobile: boolean = false;
@Input() prevPath: string = ""; @Input() prevPath: string = "";
public results: ResultLandingInfo[] = []; public results: ResultLandingInfo[] = [];
@Input() id: string; @Input() id: string;

View File

@ -145,8 +145,7 @@ export class DeletedByInferenceService {
if(author.orcid_pending) { if(author.orcid_pending) {
author.orcid_pending = author.orcid_pending.toUpperCase(); author.orcid_pending = author.orcid_pending.toUpperCase();
} }
if(result['authors'][author.rank] && result['authors'][author.rank].fullName == author.content) {
if(result['authors'][author.rank] && results['authors'][author.rank].fullName == author.content) {
if(!author.orcid && result['authors'][author.rank].orcid) { if(!author.orcid && result['authors'][author.rank].orcid) {
author.orcid = result['authors'][author.rank].orcid; author.orcid = result['authors'][author.rank].orcid;
} else if(!author.orcid_pending && result['authors'][author.rank].orcid_pending) { } else if(!author.orcid_pending && result['authors'][author.rank].orcid_pending) {

View File

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

View File

@ -4,8 +4,8 @@
[searchActionRoute]="properties.searchLinkToResults"></schema2jsonld> [searchActionRoute]="properties.searchLinkToResults"></schema2jsonld>
<!-- Desktop view --> <!-- Desktop view -->
<div id="tm-main" class="uk-visible@m landing uk-section uk-padding-remove tm-middle"> <div *ngIf="!isMobile" id="tm-main" class="landing uk-section uk-padding-remove tm-middle">
<div *ngIf="!isMobile" class="tm-main"> <div class="tm-main">
<div class="publication"> <div class="publication">
<div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar"> <div *ngIf="properties.adminToolsPortalType == 'eosc'" class="eosc-explore-back-search-bar">
<div class="uk-light uk-container uk-container-large uk-margin-left uk-height-1-1"> <div class="uk-light uk-container uk-container-large uk-margin-left uk-height-1-1">
@ -18,70 +18,6 @@
</div> </div>
</div> </div>
<div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid> <div *ngIf="!showFeedback" class="uk-grid uk-margin-remove-left" uk-grid>
<!-- left box/sidebar - actions -->
<!-- <div id="landing-left-sidebar" *ngIf="resultLandingInfo" class="uk-visible@s uk-padding-remove-horizontal">
<div class="uk-flex uk-flex-column uk-flex-between uk-flex-center uk-sticky"
uk-sticky="end: true" [attr.offset]="offset">
<div class="uk-align-center uk-text-center uk-margin-medium-top uk-flex uk-flex-column uk-flex-between">
<ng-container *ngIf="resultLandingInfo && (hasAltMetrics || hasMetrics)">
<metrics *ngIf="hasMetrics" class="uk-margin-bottom"
[pageViews]="pageViews"
[id]="id" [entityType]="'results'" [entity]="title"
[viewsFrameUrl]="viewsFrameUrl" [downloadsFrameUrl]="downloadsFrameUrl"
(metricsResults)="metricsResults($event)" [properties]=properties
[prevPath]="prevPath">
</metrics>
<altmetrics *ngIf="hasAltMetrics" id="{{resultLandingInfo.identifiers?.get('doi')[0]}}" type="doi"></altmetrics>
</ng-container>
</div>
<div class="uk-margin-large-bottom uk-align-center">
<div class="uk-text-meta uk-text-uppercase">Actions</div>
<ul class="uk-list">
<li class="uk-text-center">
<a (click)="openAddThisModal()"
[title]="'Share this '+getTypeName() + ' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
</span>
</a>
</li>
<li *ngIf="isRouteAvailable('participate/direct-claim')" class="uk-text-center"
[title]="'<span class=\'uk-flex uk-flex-middle\'>Link this '+getTypeName()+' to ...<span class=\'material-icons uk-margin-small-left\'>east</span></span>'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a [queryParams]="routerHelper.createQueryParams(['id','type','linkTo'],[id,type,'project'])"
routerLinkActive="router-link-active" routerLink="/participate/direct-claim">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="link" visuallyHidden="link"></icon>
</span>
</a>
</li>
<li class="uk-text-center">
<a (click)="openCiteModal()"
[title]="'Cite this '+getTypeName()"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="quotes" visuallyHidden="cite"></icon>
</span>
</a>
</li>
<li *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community' || properties.adminToolsPortalType == 'aggregator'"
class="uk-text-center">
<orcid-work [resultId]="id" [resultTitle]="resultLandingInfo.title" [resultLandingInfo]="resultLandingInfo"
[pids]="pidsArrayString" [pageType]="'landing'">
</orcid-work>
</li>
<li *ngIf=" properties.enableEoscDataTransfer && resultLandingInfo.resultType == 'dataset' &&
resultLandingInfo.identifiers && resultLandingInfo.identifiers.get('doi')"
class="uk-text-center">
<egi-transfer-data [dois]="resultLandingInfo.identifiers.get('doi')" [isOpen]="egiTransferModalOpen"></egi-transfer-data>
</li>
</ul>
</div>
</div>
</div> -->
<!-- center box--> <!-- center box-->
<div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default"> <div id="landing-center-content" class="uk-width-expand uk-padding-remove uk-background-default">
@ -143,7 +79,8 @@
[type]="resultLandingInfo.resultType" [type]="resultLandingInfo.resultType"
[result]="resultLandingInfo" [id]="resultLandingInfo.objIdentifier"> [result]="resultLandingInfo" [id]="resultLandingInfo.objIdentifier">
<!-- ORCID --> <!-- ORCID -->
<div *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community' || properties.adminToolsPortalType == 'aggregator'" <div *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community'
|| properties.adminToolsPortalType == 'aggregator' || properties.dashboard == 'irish'"
class="uk-margin-small-right"> class="uk-margin-small-right">
<orcid-work [resultId]="id" [resultTitle]="resultLandingInfo.title" [resultLandingInfo]="resultLandingInfo" <orcid-work [resultId]="id" [resultTitle]="resultLandingInfo.title" [resultLandingInfo]="resultLandingInfo"
[pids]="pidsArrayString" [pageType]="'landing'"> [pids]="pidsArrayString" [pageType]="'landing'">
@ -166,54 +103,6 @@
<!-- in small screens there is no sticky #graph_and_feedback so margin-top is medium (40px) --> <!-- in small screens there is no sticky #graph_and_feedback so margin-top is medium (40px) -->
<!-- else margin is medium (40px) - the actual height of uk-sticky-placeholder (graph_height - 20px -> margins of #graph_and_feedback) --> <!-- else margin is medium (40px) - the actual height of uk-sticky-placeholder (graph_height - 20px -> margins of #graph_and_feedback) -->
<div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')"> <div [attr.style]="'margin-top: '+(graph_height? 'calc(40px + 20px - '+graph_height+'px)': '40px')">
<!-- Actions for mobile viewport -->
<div class="uk-flex uk-flex-right uk-margin-medium-bottom uk-hidden@s">
<!-- Share -->
<div class="uk-margin-small-right">
<a (click)="openAddThisModal()"
[title]="'Share this '+getTypeName() + ' in your social networks'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="share" visuallyHidden="share"></icon>
</span>
</a>
</div>
<!-- Link to -->
<div *ngIf="isRouteAvailable('participate/direct-claim')" class="uk-margin-small-right"
[title]="'<span class=\'uk-flex uk-flex-middle\'>Link this '+getTypeName()+' to ...<span class=\'material-icons uk-margin-small-left\'>east</span></span>'"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<a [queryParams]="routerHelper.createQueryParams(['id','type','linkTo'],[id,type,'project'])"
routerLinkActive="router-link-active" routerLink="/participate/direct-claim">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="link" visuallyHidden="link"></icon>
</span>
</a>
</div>
<!-- Cite this -->
<div class="uk-margin-small-right">
<a (click)="openCiteModal()"
[title]="'Cite this '+getTypeName()"
[attr.uk-tooltip]="'pos: right; cls: uk-active uk-text-small uk-padding-small'">
<span class="uk-icon-button uk-icon landing-action-button landing-action-button-portal">
<icon name="quotes" visuallyHidden="cite"></icon>
</span>
</a>
</div>
<!-- ORCID -->
<div *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community' || properties.adminToolsPortalType == 'aggregator'"
class="uk-margin-small-right">
<orcid-work [resultId]="id" [resultTitle]="resultLandingInfo.title" [resultLandingInfo]="resultLandingInfo"
[pids]="pidsArrayString" [pageType]="'landing'">
</orcid-work>
</div>
<div *ngIf=" properties.enableEoscDataTransfer && resultLandingInfo.resultType == 'dataset' &&
resultLandingInfo.identifiers && resultLandingInfo.identifiers.get('doi') &&
resultLandingInfo.identifiers.get('doi').join('').indexOf('zenodo.')!=-1"
class="">
<egi-transfer-data [dois]="resultLandingInfo.identifiers.get('doi')" [isOpen]="egiTransferModalOpen"></egi-transfer-data>
</div>
</div>
<helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0" <helper *ngIf="pageContents && pageContents['top'] && pageContents['top'].length > 0"
[texts]="pageContents['top']"></helper> [texts]="pageContents['top']"></helper>
@ -232,48 +121,15 @@
[publiclyFunded]="resultLandingInfo.publiclyFunded" [publiclyFunded]="resultLandingInfo.publiclyFunded"
[projects]="resultLandingInfo.fundedByProjects"> [projects]="resultLandingInfo.fundedByProjects">
</landing-header> </landing-header>
<!-- Labels -->
<!-- Not used anymore - access labels will be in action bars, languages in the landing-header component -->
<!-- <div class="uk-margin-bottom uk-grid uk-grid-small uk-flex-middle" uk-grid>
<ng-container *ngIf="resultLandingInfo.accessMode && resultLandingInfo.accessMode.toLowerCase() !== 'not available'">
<div>
<span [class]="'uk-label uk-text-truncate '+ (accessClass(resultLandingInfo.accessMode) == 'open' ? 'uk-label-success' : '')"
title="Access Mode">{{resultLandingInfo.accessMode}}
</span>
</div>
</ng-container>
<ng-container *ngIf="resultLandingInfo.languages &&
removeUnknown(resultLandingInfo.languages).length > 0">
<ng-container *ngFor="let language of removeUnknown(resultLandingInfo.languages)">
<div>
<span class="uk-label custom-label label-language" title="Language">{{language}}</span>
</div>
</ng-container>
</ng-container>
<ng-container *ngIf="resultLandingInfo.programmingLanguages && resultLandingInfo.programmingLanguages.length > 0">
<ng-container *ngFor="let programmingLanguage of resultLandingInfo.programmingLanguages">
<div>
<span class="uk-label custom-label label-language"
title="Programming Language">{{programmingLanguage}}</span>
</div>
</ng-container>
</ng-container>
</div> -->
<div class="uk-text-small"> <div class="uk-text-small">
<!-- Identifiers --> <!-- Identifiers -->
<div *ngIf="resultLandingInfo.identifiers && resultLandingInfo.identifiers.size > 0" class="uk-margin-small-top"> <div *ngIf="resultLandingInfo.identifiers && resultLandingInfo.identifiers.size > 0" class="uk-margin-small-top">
<showIdentifiers [identifiers]="resultLandingInfo.identifiers" [showViewAll]="true"></showIdentifiers> <showIdentifiers [identifiers]="resultLandingInfo.identifiers" [showViewAll]="true"></showIdentifiers>
</div> </div>
<!--Published Date, Journal and Publisher-->
<!-- Moved inside landing-header component -->
<!-- <div showPublisher [publisher]="resultLandingInfo.publisher"
[publishDate]="resultLandingInfo.dateofacceptance"
[journal]="resultLandingInfo.journal" [properties]="properties" class="uk-margin-small-top"></div> -->
</div> </div>
</div> </div>
<div id="main-tabs-div" class="uk-sticky uk-blur-background" <div id="main-tabs-div" class="uk-sticky uk-blur-background" uk-sticky="end: true; media: @m" [attr.offset]="offset">
uk-sticky="end: true; media: @m" [attr.offset]="offset">
<div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom"> <div class="uk-padding uk-padding-remove-horizontal uk-padding-remove-bottom">
<landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'" <landing-header [ngClass]="stickyHeader ? 'uk-visible@m' : 'uk-invisible'"
[properties]="properties" [title]="resultLandingInfo.title" [properties]="properties" [title]="resultLandingInfo.title"
@ -282,7 +138,6 @@
[date]="resultLandingInfo.dateofacceptance" [embargoEndDate]="resultLandingInfo.embargoEndDate" [date]="resultLandingInfo.dateofacceptance" [embargoEndDate]="resultLandingInfo.embargoEndDate"
isSticky="true" [prevPath]="prevPath"> isSticky="true" [prevPath]="prevPath">
</landing-header> </landing-header>
<!-- <showTitle *ngIf="stickyHeader" [titleName]="resultLandingInfo.title" classNames="uk-margin-remove-bottom" class="uk-visible@m"></showTitle>-->
<my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader"> <my-tabs (selectedActiveTab)="onSelectActiveTab($event)" [offsetForSticky]="offset" [(isSticky)]="stickyHeader">
<my-tab tabTitle="Summary" [tabId]="'summary'" [active]="true"></my-tab> <my-tab tabTitle="Summary" [tabId]="'summary'" [active]="true"></my-tab>
<my-tab *ngIf="hasSubjects" <my-tab *ngIf="hasSubjects"
@ -362,26 +217,6 @@
</ng-container> </ng-container>
</div> </div>
<!-- right box/ sidebar-->
<ng-container *ngIf="!showFeedback && resultLandingInfo && hasRightSidebarInfo">
<a id="landing-right-sidebar-switcher" uk-toggle href="#right-column-offcanvas"
class="uk-offcanvas-switcher uk-flex uk-link-reset uk-flex-center uk-flex-middle uk-hidden@m"
(click)="rightSidebarOffcanvasClicked = true;">
<icon name="more" [ratio]="1.5" customClass="uk-text-primary" [flex]="true" visuallyHidden="sidebar"></icon>
</a>
<div id="right-column-offcanvas" class="uk-offcanvas" uk-offcanvas="flip: true; overlay: true;">
<div class="uk-offcanvas-bar">
<button class="uk-offcanvas-close uk-close uk-icon" type="button"
(click)="rightSidebarOffcanvasClicked = false">
<icon name="close" [ratio]="1.5" visuallyHidden="close"></icon>
</button>
<div *ngIf="rightSidebarOffcanvasClicked">
<ng-container *ngTemplateOutlet="right_column"></ng-container>
</div>
</div>
</div>
</ng-container>
<ng-template #right_column> <ng-template #right_column>
<!-- new metrics box --> <!-- new metrics box -->
<div *ngIf="resultLandingInfo && resultLandingInfo.measure && (resultLandingInfo.measure.bip.length || resultLandingInfo.measure.counts.length) && !viewAll" <div *ngIf="resultLandingInfo && resultLandingInfo.measure && (resultLandingInfo.measure.bip.length || resultLandingInfo.measure.counts.length) && !viewAll"
@ -509,11 +344,10 @@
</div> </div>
</ng-template> </ng-template>
</div> </div>
<feedback *ngIf="showFeedback && resultLandingInfo && properties.reCaptchaSiteKey" [resultLandingInfo]="resultLandingInfo"
[properties]="properties" [entityType]="getTypeName()" [fields]="feedbackFields"
[(showForm)]="showFeedback" [preSelectedField]="feedbackPreSelectedField"></feedback>
</div> </div>
<feedback *ngIf="resultLandingInfo && properties.reCaptchaSiteKey" [resultLandingInfo]="resultLandingInfo"
[properties]="properties" [entityType]="getTypeName()" [fields]="feedbackFields"
[(showForm)]="showFeedback" [preSelectedField]="feedbackPreSelectedField"></feedback>
</div> </div>
<!-- Mobile view --> <!-- Mobile view -->
@ -711,7 +545,8 @@
</div> </div>
<hr class="uk-margin-remove"> <hr class="uk-margin-remove">
</ng-container> </ng-container>
<ng-container *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community' || properties.adminToolsPortalType == 'aggregator'" > <ng-container *ngIf="properties.adminToolsPortalType == 'explore' || properties.adminToolsPortalType == 'community'
|| properties.adminToolsPortalType == 'aggregator' || properties.dashboard == 'irish'" >
<div class="uk-padding-small uk-padding-remove-horizontal "> <div class="uk-padding-small uk-padding-remove-horizontal ">
<orcid-work [resultId]="id" [resultTitle]="resultLandingInfo?.title" [resultLandingInfo]="resultLandingInfo" <orcid-work [resultId]="id" [resultTitle]="resultLandingInfo?.title" [resultLandingInfo]="resultLandingInfo"
[pids]="pidsArrayString" [pageType]="'landing'" [isMobile]="true" [pids]="pidsArrayString" [pageType]="'landing'" [isMobile]="true"
@ -886,16 +721,18 @@
</modal-alert> </modal-alert>
<modal-alert *ngIf="resultLandingInfo" #addThisModal classBody="uk-flex uk-flex-center uk-flex-middle"> <modal-alert *ngIf="resultLandingInfo" #addThisModal classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis> <addThis *ngIf="addThisClicked"></addThis>
</modal-alert> </modal-alert>
<modal-alert *ngIf="resultLandingInfo && resultLandingInfo.organizations" #organizationsModal> <modal-alert *ngIf="resultLandingInfo && resultLandingInfo.organizations" #organizationsModal>
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: resultLandingInfo.organizations.length}"></ng-container> <ng-container *ngIf="viewAllOrganizations">
<ng-container *ngTemplateOutlet="organizations_template; context: { threshold: resultLandingInfo.organizations.length}"></ng-container>
</ng-container>
</modal-alert> </modal-alert>
<modal-alert *ngIf="!isMobile && resultLandingInfo?.description" #descriptionModal <modal-alert *ngIf="!isMobile && resultLandingInfo?.description" #descriptionModal
[large]="true"> [large]="true">
<div [innerHTML]="resultLandingInfo.description"></div> <div *ngIf="descriptionClicked" [innerHTML]="resultLandingInfo.description"></div>
</modal-alert> </modal-alert>
<!--<modal-alert *ngIf="resultLandingInfo && resultLandingInfo.sdg?.length > 0"--> <!--<modal-alert *ngIf="resultLandingInfo && resultLandingInfo.sdg?.length > 0"-->
@ -1327,23 +1164,32 @@
</div> </div>
</ng-template> </ng-template>
<ng-container *ngIf="isMobile">
<fs-modal *ngIf="resultLandingInfo && resultLandingInfo.deletedByInferenceIds" #AlertModalDeletedByInferenceFS classTitle="uk-tile-default uk-border-bottom"> <fs-modal *ngIf="resultLandingInfo && resultLandingInfo.deletedByInferenceIds" #AlertModalDeletedByInferenceFS classTitle="uk-tile-default uk-border-bottom">
<deletedByInference *ngIf="type == 'publication' && deleteByInferenceOpened" <deletedByInference *ngIf="type == 'publication' && deleteByInferenceOpened"
[id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']" [id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']"
[ids]="resultLandingInfo.deletedByInferenceIds" [ids]="resultLandingInfo.deletedByInferenceIds"
[resultType]="type" [type]="openaireEntities.PUBLICATIONS"></deletedByInference> [resultType]="type" [type]="openaireEntities.PUBLICATIONS"
[isMobile]="isMobile"
[modal]="alertModalDeletedByInferenceFS"></deletedByInference>
<deletedByInference *ngIf="type == 'dataset' && deleteByInferenceOpened" <deletedByInference *ngIf="type == 'dataset' && deleteByInferenceOpened"
[id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']" [id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']"
[ids]="resultLandingInfo.deletedByInferenceIds" [ids]="resultLandingInfo.deletedByInferenceIds"
[resultType]="'dataset'" [type]="openaireEntities.DATASETS"></deletedByInference> [resultType]="'dataset'" [type]="openaireEntities.DATASETS"
[isMobile]="isMobile"
[modal]="alertModalDeletedByInferenceFS"></deletedByInference>
<deletedByInference *ngIf="type == 'software' && deleteByInferenceOpened" <deletedByInference *ngIf="type == 'software' && deleteByInferenceOpened"
[id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']" [id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']"
[ids]="resultLandingInfo.deletedByInferenceIds" [ids]="resultLandingInfo.deletedByInferenceIds"
[resultType]="type" [type]="openaireEntities.SOFTWARE"></deletedByInference> [resultType]="type" [type]="openaireEntities.SOFTWARE"
[isMobile]="isMobile"
[modal]="alertModalDeletedByInferenceFS"></deletedByInference>
<deletedByInference *ngIf="type == 'orp' && deleteByInferenceOpened" <deletedByInference *ngIf="type == 'orp' && deleteByInferenceOpened"
[id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']" [id]="resultLandingInfo.record['result']['header']['dri:objIdentifier']"
[ids]="resultLandingInfo.deletedByInferenceIds" [ids]="resultLandingInfo.deletedByInferenceIds"
[resultType]="'other'" [type]="openaireEntities.OTHER"></deletedByInference> [resultType]="'other'" [type]="openaireEntities.OTHER"
[isMobile]="isMobile"
[modal]="alertModalDeletedByInferenceFS"></deletedByInference>
</fs-modal> </fs-modal>
<fs-modal *ngIf="resultLandingInfo" #citeFsModal classTitle="uk-tile-default uk-border-bottom"> <fs-modal *ngIf="resultLandingInfo" #citeFsModal classTitle="uk-tile-default uk-border-bottom">
@ -1352,5 +1198,6 @@
</fs-modal> </fs-modal>
<fs-modal *ngIf="resultLandingInfo" #addThisFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle"> <fs-modal *ngIf="resultLandingInfo" #addThisFsModal classTitle="uk-tile-default uk-border-bottom" classBody="uk-flex uk-flex-center uk-flex-middle">
<addThis></addThis> <addThis *ngIf="addThisClicked"></addThis>
</fs-modal> </fs-modal>
</ng-container>

View File

@ -74,6 +74,8 @@ export class ResultLandingComponent {
public linkToSearchPage: string = null; public linkToSearchPage: string = null;
public citeThisClicked: boolean; public citeThisClicked: boolean;
public addThisClicked: boolean;
public descriptionClicked: boolean;
// Metrics tab variables // Metrics tab variables
public metricsClicked: boolean; public metricsClicked: boolean;
@ -197,6 +199,9 @@ export class ResultLandingComponent {
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private layoutService: LayoutService, private layoutService: LayoutService,
private _contextService: ContextsService) { private _contextService: ContextsService) {
if(route.snapshot.data && route.snapshot.data['type']) {
this.type = route.snapshot.data['type'];
}
} }
ngOnInit() { ngOnInit() {
@ -864,6 +869,7 @@ export class ResultLandingComponent {
} }
public openAddThisModal() { public openAddThisModal() {
this.addThisClicked = true;
this.addThisModal.cancelButton = false; this.addThisModal.cancelButton = false;
this.addThisModal.okButton = false; this.addThisModal.okButton = false;
this.addThisModal.alertTitle = "Share this " + this.getTypeName() + " in your social networks"; this.addThisModal.alertTitle = "Share this " + this.getTypeName() + " in your social networks";
@ -1076,6 +1082,7 @@ export class ResultLandingComponent {
this.sdgFosSuggest.subjectType="fos"; this.sdgFosSuggest.subjectType="fos";
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
this.sdgFosSuggest.isOpen = true;
this.sdgFosSuggest.openSelectionModal(); this.sdgFosSuggest.openSelectionModal();
} }
@ -1090,6 +1097,7 @@ export class ResultLandingComponent {
} }
public openDescriptionModal() { public openDescriptionModal() {
this.descriptionClicked = true;
this.descriptionModal.alertFooter = false; this.descriptionModal.alertFooter = false;
this.descriptionModal.alertTitle = "Abstract"; this.descriptionModal.alertTitle = "Abstract";
this.descriptionModal.open(); this.descriptionModal.open();

View File

@ -26,7 +26,6 @@ import {ResultPreviewModule} from "../../utils/result-preview/result-preview.mod
import {FeedbackModule} from "../feedback/feedback.module"; import {FeedbackModule} from "../feedback/feedback.module";
import {TabsModule} from "../../utils/tabs/tabs.module"; import {TabsModule} from "../../utils/tabs/tabs.module";
import {LoadingModule} from "../../utils/loading/loading.module"; import {LoadingModule} from "../../utils/loading/loading.module";
import {OrcidModule} from "../../orcid/orcid.module";
import {IconsModule} from "../../utils/icons/icons.module"; import {IconsModule} from "../../utils/icons/icons.module";
import {IconsService} from "../../utils/icons/icons.service"; import {IconsService} from "../../utils/icons/icons.service";
import {cite, fire, graph, landmark, link, link_to, quotes, rocket, versions} from "../../utils/icons/icons"; 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 {FullScreenModalModule} from "../../utils/modal/full-screen-modal/full-screen-modal.module";
import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module'; import {SafeHtmlPipeModule} from '../../utils/pipes/safeHTMLPipe.module';
import {EntityActionsModule} from "../../utils/entity-actions/entity-actions.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({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, LandingModule, SharedModule, RouterModule, CommonModule, FormsModule, LandingModule, SharedModule, RouterModule,
ResultLandingRoutingModule,
CiteThisModule, PagingModule, IFrameModule, CiteThisModule, PagingModule, IFrameModule,
AltMetricsModule, Schema2jsonldModule, SEOServiceModule, AltMetricsModule, Schema2jsonldModule, SEOServiceModule,
DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule, DeletedByInferenceModule, ShowAuthorsModule, HelperModule, ResultLandingUtilsModule, AlertModalModule,
LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule, LandingHeaderModule, NoLoadPaging, ResultPreviewModule, FeedbackModule, TabsModule, LoadingModule,
OrcidModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule, OrcidCoreModule, IconsModule, InputModule, EGIDataTransferModule, RecaptchaModule,
SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule SdgFosSuggestModule, FullScreenModalModule, SafeHtmlPipeModule, EntityActionsModule
], ],
declarations: [ declarations: [

View File

@ -3,7 +3,7 @@ import { Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@a
import {Observable} from 'rxjs'; import {Observable} from 'rxjs';
import {LoginErrorCodes} from './utils/guardHelper.class'; import {LoginErrorCodes} from './utils/guardHelper.class';
@Injectable() @Injectable({providedIn: 'root'})
export class FreeGuard { export class FreeGuard {
constructor(private router: Router) { constructor(private router: Router) {

View File

@ -7,16 +7,13 @@ import {UserRoutingModule} from './user-routing.module';
import {UserComponent} from './user.component'; import {UserComponent} from './user.component';
import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard';
import {LoadingModule} from "../utils/loading/loading.module"; import {LoadingModule} from "../utils/loading/loading.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, UserRoutingModule, RouterModule, LoadingModule CommonModule, FormsModule, UserRoutingModule, RouterModule, LoadingModule
], ],
providers: [ providers: [],
PreviousRouteRecorder
],
declarations: [ declarations: [
UserComponent UserComponent
], ],

View File

@ -234,12 +234,13 @@ export class Role {
} }
public static mapType(type: string, communityMap: boolean = true): string { public static mapType(type: string, communityMap: boolean = true): string {
type = type.replace(this.GROUP, '');
if (type == "ri" && communityMap) { if (type == "ri" && communityMap) {
type = "community"; type = "community";
} else if (type == "organization") { } else if (type == "organization") {
type = "institution"; type = "institution";
} }
return Role.GROUP + type; return type;
} }
/** /**

View File

@ -20,7 +20,7 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
template: ` template: `
<div class="uk-margin-medium-bottom"> <div class="uk-margin-medium-bottom">
<form *ngIf="stakeholderFb" [formGroup]="stakeholderFb"> <form *ngIf="stakeholderFb" [formGroup]="stakeholderFb">
<div class="uk-grid uk-grid-large" uk-grid> <div class="uk-grid" uk-grid>
<div class="uk-width-1-2@m"> <div class="uk-width-1-2@m">
<div input id="name" [formInput]="stakeholderFb.get('name')" <div input id="name" [formInput]="stakeholderFb.get('name')"
placeholder="Name"></div> placeholder="Name"></div>
@ -126,6 +126,19 @@ import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
</div> </div>
</div> </div>
</div> </div>
<div *ngIf="canChangeCopy" class="uk-width-1-1">
<h6>Instance Type</h6>
<div class="uk-width-auto uk-flex uk-flex-middle">
<label class="uk-margin-right">
<input type="radio" [value]="true" formControlName="copy"/>
<span class="uk-margin-xsmall-left">Copy</span>
</label>
<label class="uk-margin-right">
<input type="radio" [value]="false" formControlName="copy"/>
<span class="uk-margin-xsmall-left">Reference</span>
</label>
</div>
</div>
</div> </div>
</form> </form>
<div #notify [class.uk-hidden]="!stakeholderFb" notify-form <div #notify [class.uk-hidden]="!stakeholderFb" notify-form
@ -145,6 +158,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
public stakeholder: Stakeholder; public stakeholder: Stakeholder;
public isDefault: boolean; public isDefault: boolean;
public isNew: boolean; public isNew: boolean;
public isFull: boolean;
public loading: boolean = false; public loading: boolean = false;
public typesByRole: Option[]; public typesByRole: Option[];
public statsProfiles: string[]; public statsProfiles: string[];
@ -172,7 +186,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
super.ngOnDestroy(); super.ngOnDestroy();
} }
public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean) { public init(stakeholder: Stakeholder, alias: string[], defaultStakeholders: Stakeholder[], isDefault: boolean, isNew: boolean, isFull: boolean = false) {
this.reset(); this.reset();
this.deleteCurrentPhoto = false; this.deleteCurrentPhoto = false;
this.stakeholder = stakeholder; this.stakeholder = stakeholder;
@ -183,6 +197,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
this.defaultStakeholders = defaultStakeholders; this.defaultStakeholders = defaultStakeholders;
this.isDefault = isDefault; this.isDefault = isDefault;
this.isNew = isNew; this.isNew = isNew;
this.isFull = isFull;
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user; this.user = user;
if (this.isCurator) { if (this.isCurator) {
@ -220,6 +235,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
funderType: this.fb.control(this.stakeholder.funderType), funderType: this.fb.control(this.stakeholder.funderType),
topics: this.fb.control(this.stakeholder.topics), topics: this.fb.control(this.stakeholder.topics),
isUpload: this.fb.control(this.stakeholder.isUpload), isUpload: this.fb.control(this.stakeholder.isUpload),
copy: this.fb.control(this.stakeholder.copy),
logoUrl: this.fb.control(this.stakeholder.logoUrl), logoUrl: this.fb.control(this.stakeholder.logoUrl),
}); });
if (this.stakeholder.isUpload) { if (this.stakeholder.isUpload) {
@ -246,7 +262,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => { this.subscriptions.push(this.stakeholderFb.get('type').valueChanges.subscribe(value => {
this.onTypeChange(value, defaultStakeholders); 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) { if (!this.isNew) {
this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); this.notification = NotificationUtils.editStakeholder(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name);
this.notify.reset(this.notification.message); 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; 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() { reset() {
this.uploadError = null; this.uploadError = null;
this.stakeholderFb = null; this.stakeholderFb = null;
@ -350,15 +373,15 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
public saveStakeholder(callback: Function, errorCallback: Function = null) { public saveStakeholder(callback: Function, errorCallback: Function = null) {
if (this.isNew) { if (this.isNew) {
let defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId); let copyId = null;
this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(),
(defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault));
this.removePhoto();
if (this.stakeholderFb.getRawValue().isDefault) { if (this.stakeholderFb.getRawValue().isDefault) {
copyId = this.stakeholderFb.getRawValue().defaultId !== '-1'?this.stakeholderFb.getRawValue().defaultId:null;
this.stakeholderFb.get('defaultId').setValue(null); this.stakeholderFb.get('defaultId').setValue(null);
this.stakeholderFb.removeControl('isDefault');
} }
this.removePhoto();
this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, 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.entity = stakeholder._id;
this.notification.stakeholder = stakeholder.alias; this.notification.stakeholder = stakeholder.alias;
this.notification.stakeholderType = stakeholder.type; this.notification.stakeholderType = stakeholder.type;
@ -375,7 +398,7 @@ export class EditStakeholderComponent extends StakeholderBaseComponent {
this.loading = false; this.loading = false;
})); }));
} else { } 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.entity = stakeholder._id;
this.notification.stakeholder = stakeholder.alias; this.notification.stakeholder = stakeholder.alias;
this.notification.stakeholderType = stakeholder.type; this.notification.stakeholderType = stakeholder.type;

View File

@ -5,9 +5,10 @@ import {InputModule} from "../../../sharedComponents/input/input.module";
import {ReactiveFormsModule} from "@angular/forms"; import {ReactiveFormsModule} from "@angular/forms";
import {IconsModule} from "../../../utils/icons/icons.module"; import {IconsModule} from "../../../utils/icons/icons.module";
import {NotifyFormModule} from "../../../notifications/notify-form/notify-form.module"; import {NotifyFormModule} from "../../../notifications/notify-form/notify-form.module";
import {MatSlideToggleModule} from "@angular/material/slide-toggle";
@NgModule({ @NgModule({
imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule], imports: [CommonModule, InputModule, ReactiveFormsModule, IconsModule, NotifyFormModule, MatSlideToggleModule],
declarations: [EditStakeholderComponent], declarations: [EditStakeholderComponent],
exports: [EditStakeholderComponent] exports: [EditStakeholderComponent]
}) })

View File

@ -48,7 +48,7 @@ export class GeneralComponent extends BaseComponent implements OnInit {
} }
public reset() { 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() { public save() {

View File

@ -1,7 +1,6 @@
import {NgModule} from "@angular/core"; import {NgModule} from "@angular/core";
import {GeneralComponent} from "./general.component"; import {GeneralComponent} from "./general.component";
import {GeneralRoutingModule} from "./general-routing.module"; import {GeneralRoutingModule} from "./general-routing.module";
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
import {CommonModule} from "@angular/common"; import {CommonModule} from "@angular/common";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {InputModule} from "../../sharedComponents/input/input.module"; import {InputModule} from "../../sharedComponents/input/input.module";
@ -30,9 +29,7 @@ import {
LogoUrlPipeModule, LogoUrlPipeModule,
SidebarMobileToggleModule SidebarMobileToggleModule
], ],
providers: [ providers: [],
PreviousRouteRecorder,
],
exports: [GeneralComponent] exports: [GeneralComponent]
}) })
export class GeneralModule { export class GeneralModule {

View File

@ -12,14 +12,13 @@
</div> </div>
<div actions> <div actions>
<div class="uk-section-xsmall"> <div class="uk-section-xsmall">
<div class="uk-flex uk-flex-center uk-flex-wrap uk-flex-middle" <div class="uk-flex uk-flex-center uk-flex-wrap uk-flex-middle uk-flex-between@m">
[ngClass]="properties.dashboard == 'irish' ? 'uk-flex-between@m' : 'uk-flex-right@m'"> <div class="uk-width-medium uk-margin-small-bottom">
<div *ngIf="properties.dashboard == 'irish'" class="uk-width-medium uk-margin-small-bottom"> <div input type="select" placeholder="Type" [disabled]="loading"
<div input type="select" placeholder="Type"
[options]="typeOptions" [formInput]="filters.get('type')"> [options]="typeOptions" [formInput]="filters.get('type')">
</div> </div>
</div> </div>
<div search-input [searchControl]="filters.get('keyword')" [expandable]="true" <div search-input [searchControl]="filters.get('keyword')" [expandable]="true" [disabled]="loading"
placeholder="Search Profiles" searchInputClass="outer" placeholder="Search Profiles" searchInputClass="outer"
class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div> class="uk-width-1-3@xl uk-width-2-5@l uk-width-1-2@m uk-width-1-1 uk-flex uk-flex-right"></div>
</div> </div>
@ -32,7 +31,7 @@
<div *ngIf="!loading" uk-height-match="target: .titleContainer; row: false"> <div *ngIf="!loading" uk-height-match="target: .titleContainer; row: false">
<div uk-height-match="target: .logoContainer; row: false"> <div uk-height-match="target: .logoContainer; row: false">
<div *ngIf="tab != 'profiles' && isCurator()" class="uk-section"> <div *ngIf="tab != 'profiles' && isCurator()" class="uk-section">
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-small-bottom"> <div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
<h4 class="uk-margin-remove">Profile Templates</h4> <h4 class="uk-margin-remove">Profile Templates</h4>
<paging-no-load *ngIf="displayDefaultStakeholders?.length > pageSize" <paging-no-load *ngIf="displayDefaultStakeholders?.length > pageSize"
(pageChange)="updateCurrentTemplatesPage($event)" (pageChange)="updateCurrentTemplatesPage($event)"
@ -40,8 +39,7 @@
[totalResults]="displayDefaultStakeholders.length"> [totalResults]="displayDefaultStakeholders.length">
</paging-no-load> </paging-no-load>
</div> </div>
<div class="uk-grid uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1 uk-grid-match" <div class="uk-grid uk-child-width-1-3@l uk-child-width-1-2@m uk-child-width-1-1 uk-grid-match" uk-grid>
uk-grid>
<ng-template ngFor <ng-template ngFor
[ngForOf]="displayDefaultStakeholders.slice((currentTemplatesPage-1)*pageSize, currentTemplatesPage*pageSize)" [ngForOf]="displayDefaultStakeholders.slice((currentTemplatesPage-1)*pageSize, currentTemplatesPage*pageSize)"
let-stakeholder> let-stakeholder>
@ -60,7 +58,7 @@
</h4> </h4>
</div> </div>
<div *ngIf="tab != 'templates' && isManager()" class="uk-section"> <div *ngIf="tab != 'templates' && isManager()" class="uk-section">
<div class="uk-flex uk-flex-middle uk-flex-between uk-margin-small-bottom"> <div class="uk-flex uk-flex-middle uk-flex-between uk-margin-bottom">
<h4 class="uk-margin-remove">Profiles</h4> <h4 class="uk-margin-remove">Profiles</h4>
<paging-no-load *ngIf="displayStakeholders?.length > pageSize" <paging-no-load *ngIf="displayStakeholders?.length > pageSize"
(pageChange)="updateCurrentPage($event)" (pageChange)="updateCurrentPage($event)"

View File

@ -1,7 +1,6 @@
import {NgModule} from "@angular/core"; import {NgModule} from "@angular/core";
import {ManageStakeholdersComponent} from "./manageStakeholders.component"; import {ManageStakeholdersComponent} from "./manageStakeholders.component";
import {ManageStakeholdersRoutingModule} from "./manageStakeholders-routing.module"; import {ManageStakeholdersRoutingModule} from "./manageStakeholders-routing.module";
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
import {CommonModule} from "@angular/common"; import {CommonModule} from "@angular/common";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {InputModule} from "../../sharedComponents/input/input.module"; import {InputModule} from "../../sharedComponents/input/input.module";
@ -40,9 +39,7 @@ import {PagingModule} from "../../utils/paging.module";
SliderTabsModule, SliderTabsModule,
PagingModule PagingModule
], ],
providers: [ providers: [],
PreviousRouteRecorder,
],
exports: [ManageStakeholdersComponent] exports: [ManageStakeholdersComponent]
}) })
export class ManageStakeholdersModule { export class ManageStakeholdersModule {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,12 +28,15 @@
</span> </span>
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="topicIndex !== i" <span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="topicIndex !== i"
(click)="$event.stopPropagation();$event.preventDefault()"> (click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle"> <icon *ngIf="!isEditable && showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(topic.visibility)"
ratio="0.6"></icon>
<a *ngIf="isEditable && (isCurator || showVisibility)" class="uk-link-reset uk-flex uk-flex-middle">
<icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(topic.visibility)" <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(topic.visibility)"
ratio="0.6"></icon> ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body"> <div #element *ngIf="isEditable && (isCurator || showVisibility)"
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator"> <ng-container *ngIf="isCurator">
<li> <li>
@ -106,12 +109,14 @@
<span class="uk-width-expand uk-text-truncate">{{category.name}}</span> <span class="uk-width-expand uk-text-truncate">{{category.name}}</span>
<span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="categoryIndex !== j" <span class="uk-margin-xsmall-left hide-on-close" [class.uk-invisible-hover]="categoryIndex !== j"
(click)="$event.stopPropagation();$event.preventDefault()"> (click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle"> <icon *ngIf="!isEditable && showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(category.visibility)"
ratio="0.6"></icon>
<a *ngIf="isEditable && (isCurator || showVisibility)" class="uk-link-reset uk-flex uk-flex-middle">
<icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(category.visibility)" <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(category.visibility)"
ratio="0.6"></icon> ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element <div #element *ngIf="isEditable && (isCurator || showVisibility)"
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body"> uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; flip: false; container: body">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator"> <ng-container *ngIf="isCurator">
@ -175,7 +180,7 @@
</div> </div>
</a> </a>
</li> </li>
<li *ngIf="isCurator"> <li *ngIf="isCurator && isEditable">
<a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle"> <a (click)="editCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon> <icon name="add" [flex]="true"></icon>
<span class="hide-on-close">Create new category</span> <span class="hide-on-close">Create new category</span>
@ -183,7 +188,7 @@
</li> </li>
</ul> </ul>
</li> </li>
<li *ngIf="isCurator" class="hide-on-close"> <li *ngIf="isCurator && isEditable" class="hide-on-close">
<a (click)="editTopicOpen(-1); $event.preventDefault()"> <a (click)="editTopicOpen(-1); $event.preventDefault()">
<div class="uk-flex uk-flex-middle"> <div class="uk-flex uk-flex-middle">
<div class="uk-width-auto"> <div class="uk-width-auto">
@ -235,12 +240,15 @@
<span class="uk-flex uk-flex-column uk-flex-center uk-margin-small-left" <span class="uk-flex uk-flex-column uk-flex-center uk-margin-small-left"
[class.uk-invisible-hover]="subCategoryIndex !== i" [class.uk-invisible-hover]="subCategoryIndex !== i"
(click)="$event.stopPropagation();$event.preventDefault()"> (click)="$event.stopPropagation();$event.preventDefault()">
<a class="uk-link-reset uk-flex uk-flex-middle"> <icon *ngIf="!isEditable && showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(subCategory.visibility)"
ratio="0.6"></icon>
<a *ngIf="isEditable && (isCurator || showVisibility)" class="uk-link-reset uk-flex uk-flex-middle">
<icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(subCategory.visibility)" <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(subCategory.visibility)"
ratio="0.6"></icon> ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; container: body"> <div #element *ngIf="isEditable && (isCurator || showVisibility)"
uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0; container: body">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator"> <ng-container *ngIf="isCurator">
<li> <li>
@ -318,7 +326,7 @@
</span> </span>
</li> </li>
</ng-template> </ng-template>
<li *ngIf="isCurator"> <li *ngIf="isCurator && isEditable">
<a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle"> <a (click)="editSubCategoryOpen(); $event.preventDefault()" class="uk-flex uk-flex-middle">
<icon name="add" [flex]="true"></icon> <icon name="add" [flex]="true"></icon>
<span class="uk-text-uppercase">Create new subcategory</span> <span class="uk-text-uppercase">Create new subcategory</span>

View File

@ -242,30 +242,18 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
} }
topicChanged(callback: Function, save: boolean = false) { topicChanged(callback: Function, save: boolean = false) {
if(this.topics && save) {
this.topics.disable();
}
if(this.categories) {
this.categories.disable();
}
if(this.subCategories) {
this.subCategories.disable();
}
if(callback) { if(callback) {
callback(); callback();
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
if(this.topics && save) { if(this.topics && save) {
this.topics.init(); this.topics.init();
this.topics.enable();
} }
if(this.categories) { if(this.categories) {
this.categories.init(); this.categories.init();
this.categories.enable();
} }
if(this.subCategories) { if(this.subCategories) {
this.subCategories.init(); this.subCategories.init();
this.subCategories.enable();
} }
} }
@ -359,6 +347,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
this.stakeholder.topics.splice(this.index, 1); this.stakeholder.topics.splice(this.index, 1);
if(this.topicIndex === this.index) { if(this.topicIndex === this.index) {
this.chooseTopic(Math.max(0, this.index - 1)); this.chooseTopic(Math.max(0, this.index - 1));
} else if(this.topicIndex > this.index) {
this.chooseTopic(this.topicIndex - 1);
} }
}, true); }, true);
}; };
@ -388,23 +378,15 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
} }
categoryChanged(callback: Function, save: boolean = false) { categoryChanged(callback: Function, save: boolean = false) {
if(this.categories && save) {
this.categories.disable();
}
if(this.subCategories) {
this.subCategories.disable();
}
if(callback) { if(callback) {
callback(); callback();
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
if(this.categories && save) { if(this.categories && save) {
this.categories.init(); this.categories.init();
this.categories.enable();
} }
if(this.subCategories) { if(this.subCategories) {
this.subCategories.init(); this.subCategories.init();
this.subCategories.enable();
} }
} }
@ -500,6 +482,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1); this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
if(this.categoryIndex === this.index) { if(this.categoryIndex === this.index) {
this.chooseCategory(Math.max(0, this.index - 1)); this.chooseCategory(Math.max(0, this.index - 1));
} else if(this.categoryIndex > this.index) {
this.chooseCategory(this.categoryIndex - 1);
} }
}, true); }, true);
}; };
@ -528,16 +512,12 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
} }
subCategoryChanged(callback: Function, save: boolean = false) { subCategoryChanged(callback: Function, save: boolean = false) {
if(this.subCategories && save) {
this.subCategories.disable();
}
if(callback) { if(callback) {
callback(); callback();
} }
this.cdr.detectChanges(); this.cdr.detectChanges();
if(this.subCategories && save) { if(this.subCategories && save) {
this.subCategories.init(); this.subCategories.init();
this.subCategories.enable();
} }
} }
@ -640,6 +620,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1); this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1);
if(this.subCategoryIndex === this.index) { if(this.subCategoryIndex === this.index) {
this.chooseSubcategory(Math.max(0, this.index - 1)); this.chooseSubcategory(Math.max(0, this.index - 1));
} else if(this.subCategoryIndex > this.index) {
this.chooseSubcategory(this.subCategoryIndex - 1);
} }
}, true); }, true);
}; };
@ -777,4 +759,8 @@ export class TopicComponent extends StakeholderBaseComponent implements OnInit,
this.visibilityModal.alertFooter = false; this.visibilityModal.alertFooter = false;
this.visibilityModal.open(); this.visibilityModal.open();
} }
get isEditable(): boolean {
return this.stakeholder.copy || this.stakeholder.defaultId == null || this.stakeholder.defaultId == '-1';
}
} }

View File

@ -1,9 +1,6 @@
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {PreviousRouteRecorder} from '../../utils/piwik/previousRouteRecorder.guard';
import {PiwikService} from '../../utils/piwik/piwik.service';
import {TopicComponent} from "./topic.component"; import {TopicComponent} from "./topic.component";
import {TopicRoutingModule} from "./topic-routing.module"; import {TopicRoutingModule} from "./topic-routing.module";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
@ -22,22 +19,18 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
import {TransitionGroupModule} from "../../utils/transition-group/transition-group.module"; import {TransitionGroupModule} from "../../utils/transition-group/transition-group.module";
import {NumberRoundModule} from "../../utils/pipes/number-round.module"; import {NumberRoundModule} from "../../utils/pipes/number-round.module";
import {SideBarModule} from "../../dashboard/sharedComponents/sidebar/sideBar.module"; import {SideBarModule} from "../../dashboard/sharedComponents/sidebar/sideBar.module";
import { import {SidebarMobileToggleModule} from "../../dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
SidebarMobileToggleModule import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module";
} from "../../dashboard/sharedComponents/sidebar/sidebar-mobile-toggle/sidebar-mobile-toggle.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule, CommonModule, TopicRoutingModule, ClickModule, RouterModule, FormsModule, AlertModalModule,
ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule ReactiveFormsModule, InputModule, IconsModule, PageContentModule, LoadingModule, NotifyFormModule, LogoUrlPipeModule, TransitionGroupModule, NumberRoundModule, SideBarModule, SidebarMobileToggleModule, SliderTabsModule
], ],
declarations: [ declarations: [
TopicComponent, IndicatorsComponent TopicComponent, IndicatorsComponent
], ],
providers: [ providers: [],
PreviousRouteRecorder,
PiwikService
],
exports: [ exports: [
TopicComponent TopicComponent
] ]

View File

@ -17,6 +17,11 @@ import {Session} from "../../login/utils/helper.class";
import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {properties} from "src/environments/environment"; import {properties} from "src/environments/environment";
class Roles {
manager = 'manager';
member = 'member';
}
class Entities { class Entities {
stakeholder = 'Dashboard'; stakeholder = 'Dashboard';
funder = 'Funder'; funder = 'Funder';
@ -37,6 +42,7 @@ class Entities {
} }
export class StakeholderConfiguration { export class StakeholderConfiguration {
public static ROLES: Roles = new Roles();
public static ENTITIES: Entities = new Entities(); public static ENTITIES: Entities = new Entities();
public static TYPES: Option[] = [ public static TYPES: Option[] = [
{value: 'funder', label: StakeholderConfiguration.ENTITIES.funder}, {value: 'funder', label: StakeholderConfiguration.ENTITIES.funder},
@ -55,9 +61,15 @@ export class StakeholderConfiguration {
{icon: 'incognito', value: "PRIVATE", label: 'Private'}, {icon: 'incognito', value: "PRIVATE", label: 'Private'},
]; ];
public static CACHE_INDICATORS: boolean = true; public static CACHE_INDICATORS: boolean = true;
public static NUMBER_MULTI_INDICATOR_PATHS = false;
public static CHART_MULTI_INDICATOR_PATHS = true;
} }
export class StakeholderUtils { export class StakeholderUtils {
get roles() {
return StakeholderConfiguration.ROLES;
}
get entities() { get entities() {
return StakeholderConfiguration.ENTITIES; return StakeholderConfiguration.ENTITIES;
} }
@ -82,10 +94,18 @@ export class StakeholderUtils {
return StakeholderConfiguration.CACHE_INDICATORS; return StakeholderConfiguration.CACHE_INDICATORS;
} }
get hasMultiNumberIndicatorPaths() {
return StakeholderConfiguration.NUMBER_MULTI_INDICATOR_PATHS;
}
get hasMultiChartIndicatorPaths() {
return StakeholderConfiguration.CHART_MULTI_INDICATOR_PATHS;
}
visibilityIcon: Map<Visibility, string> = new Map<Visibility, string>(this.visibilities.map(option => [option.value, option.icon])); visibilityIcon: Map<Visibility, string> = new Map<Visibility, string>(this.visibilities.map(option => [option.value, option.icon]));
defaultValue(options: Option[]) { defaultValue(options: Option[]) {
return options.length === 1?options[0].value:null; return options.length === 1 ? options[0].value : null;
} }
showField(options: Option[]) { showField(options: Option[]) {
@ -94,7 +114,7 @@ export class StakeholderUtils {
getLabel(options: Option[], value) { getLabel(options: Option[], value) {
let option = options.find(option => option.value === value); let option = options.find(option => option.value === value);
return option?option.label:null; return option ? option.label : null;
} }
getTypesByUserRoles(user, id: string = null): Option[] { getTypesByUserRoles(user, id: string = null): Option[] {
@ -107,60 +127,6 @@ export class StakeholderUtils {
return types; return types;
} }
public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[], isDefault: boolean = false): Stakeholder {
funder.topics = HelperFunctions.copy(defaultTopics);
for (let topic of funder.topics) {
topic.defaultId = !isDefault ? topic._id : null;
topic._id = null;
for (let category of topic.categories) {
category.defaultId = !isDefault ? category._id : null;
category._id = null;
let subTokeep: SubCategory[] = [];
for (let subCategory of category.subCategories) {
subCategory.defaultId = !isDefault ? subCategory._id : null;
subCategory._id = null;
subTokeep.push(subCategory);
for (let section of subCategory.charts) {
let chartsTokeep: Indicator[] = [];
section.defaultId = !isDefault ? section._id : null;
section.stakeholderAlias = funder.alias;
section._id = null;
for (let indicator of section.indicators) {
indicator.defaultId = !isDefault ? indicator._id : null;
indicator._id = null;
chartsTokeep.push(indicator);
for (let indicatorPath of indicator.indicatorPaths) {
if (indicatorPath.parameters) {
Object.keys(indicatorPath.parameters).forEach(key => {
if (key == "index_name") {
indicatorPath.parameters[key] = funder.index_name;
} else if (key == "index_id") {
indicatorPath.parameters[key] = funder.index_id;
} else if (key == "index_shortName") {
indicatorPath.parameters[key] = funder.index_shortName.toLowerCase();
}
});
}
}
}
section.indicators = chartsTokeep;
}
for (let section of subCategory.numbers) {
section.defaultId = !isDefault ? section._id : null;
section.stakeholderAlias = funder.alias;
section._id = null;
for (let indicator of section.indicators) {
indicator.defaultId = !isDefault ? indicator._id : null;
indicator._id = null;
}
}
}
category.subCategories = subTokeep;
}
}
return funder;
}
aliasValidatorString(elements: string[]): ValidatorFn { aliasValidatorString(elements: string[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: string } | null => { return (control: AbstractControl): { [key: string]: string } | null => {
@ -317,9 +283,14 @@ export class IndicatorUtils {
public getFullUrl(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string { public getFullUrl(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null): string {
let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url;
if (stakeholder.statsProfile) { if (indicatorPath.parameters.statsProfile) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(indicatorPath.parameters.statsProfile)
} else if (stakeholder.statsProfile) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile) replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile)
} }
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(stakeholder.index_id);
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(stakeholder.index_shortName);
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(stakeholder.index_name);
if (indicatorPath.parameters) { if (indicatorPath.parameters) {
Object.keys(indicatorPath.parameters).forEach(key => { Object.keys(indicatorPath.parameters).forEach(key => {
let replacedValue = indicatorPath.parameters[key]; let replacedValue = indicatorPath.parameters[key];
@ -329,16 +300,6 @@ export class IndicatorUtils {
if (endYear && key == "end_year" && indicatorPath.filters["end_year"]) { if (endYear && key == "end_year" && indicatorPath.filters["end_year"]) {
replacedValue = (replacedValue > endYear) ? endYear : replacedValue; replacedValue = (replacedValue > endYear) ? endYear : replacedValue;
} }
if (key == "index_id") {
replacedValue = stakeholder.index_id;
}
if (key == "index_name") {
replacedValue = stakeholder.index_name;
}
if (key == "index_shortName") {
replacedValue = stakeholder.index_shortName.toLowerCase();
}
replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue)
}); });
} }
@ -392,19 +353,24 @@ export class IndicatorUtils {
return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl);
} }
public getFullUrlWithFilters(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded: boolean = false, foslvl1:string[]=[], foslvl2:string[]=[], publiclyFunded: "all"| "true"| "false"= "all" ): string { public getFullUrlWithFilters(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded: boolean = false, foslvl1: string[] = [], foslvl2: string[] = [], publiclyFunded: "all" | "true" | "false" = "all"): string {
let filterSubtitleText = []; let filterSubtitleText = [];
indicatorPath.filtersApplied = 0; indicatorPath.filtersApplied = 0;
let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url;
if (stakeholder.statsProfile) { if (indicatorPath.parameters.statsProfile) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile); replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(indicatorPath.parameters.statsProfile)
} else if (stakeholder.statsProfile) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + this.statsProfileParameter + ChartHelper.suffix).join(stakeholder.statsProfile)
} }
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(stakeholder.index_id);
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(stakeholder.index_shortName);
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(stakeholder.index_name);
if (fundingL0) { if (fundingL0) {
if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
let filterResults = this.addFilter(replacedUrl, 'fundingL0', fundingL0); let filterResults = this.addFilter(replacedUrl, 'fundingL0', fundingL0);
replacedUrl = filterResults.url; replacedUrl = filterResults.url;
indicatorPath.filtersApplied += filterResults.filtersApplied; indicatorPath.filtersApplied += filterResults.filtersApplied;
filterSubtitleText.push( "Funding level 0: " ) ; filterSubtitleText.push("Funding level 0: ");
} }
} }
if (startYear) { if (startYear) {
@ -421,7 +387,7 @@ export class IndicatorUtils {
indicatorPath.filtersApplied += filterResults.filtersApplied; indicatorPath.filtersApplied += filterResults.filtersApplied;
} }
} }
if(startYear || endYear) { if (startYear || endYear) {
filterSubtitleText.push(startYear && endYear ? (startYear + ' - ' + endYear) : (endYear ? ('until ' + endYear) : '')); filterSubtitleText.push(startYear && endYear ? (startYear + ' - ' + endYear) : (endYear ? ('until ' + endYear) : ''));
} }
if (coFunded) { if (coFunded) {
@ -429,44 +395,33 @@ export class IndicatorUtils {
let filterResults = this.addFilter(replacedUrl, 'co-funded', coFunded); let filterResults = this.addFilter(replacedUrl, 'co-funded', coFunded);
replacedUrl = filterResults.url; replacedUrl = filterResults.url;
indicatorPath.filtersApplied += filterResults.filtersApplied; indicatorPath.filtersApplied += filterResults.filtersApplied;
filterSubtitleText.push( "Co-funded: " + (coFunded?'yes':'no') ) ; filterSubtitleText.push("Co-funded: " + (coFunded ? 'yes' : 'no'));
} }
} }
if (publiclyFunded && publiclyFunded !="all") { if (publiclyFunded && publiclyFunded != "all") {
if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
let filterResults = this.addFilter(replacedUrl, 'publicly-funded', publiclyFunded); let filterResults = this.addFilter(replacedUrl, 'publicly-funded', publiclyFunded);
replacedUrl = filterResults.url; replacedUrl = filterResults.url;
indicatorPath.filtersApplied += filterResults.filtersApplied; indicatorPath.filtersApplied += filterResults.filtersApplied;
filterSubtitleText.push( "Publicly funded: " + (publiclyFunded?'yes':'no') ) ; filterSubtitleText.push("Publicly funded: " + (publiclyFunded ? 'yes' : 'no'));
} }
} }
if (foslvl1) { if (foslvl1) {
if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
let filterResults = this.addFilter(replacedUrl, 'foslvl1', foslvl1); let filterResults = this.addFilter(replacedUrl, 'foslvl1', foslvl1);
replacedUrl = filterResults.url; replacedUrl = filterResults.url;
indicatorPath.filtersApplied +=filterResults.filtersApplied?foslvl1.length:0; indicatorPath.filtersApplied += filterResults.filtersApplied ? foslvl1.length : 0;
} }
} }
if (foslvl2) { if (foslvl2) {
if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) { if (indicatorPath.source == "stats-tool" && indicatorPath.chartObject) {
let filterResults = this.addFilter(replacedUrl, 'foslvl2', foslvl2); let filterResults = this.addFilter(replacedUrl, 'foslvl2', foslvl2);
replacedUrl = filterResults.url; replacedUrl = filterResults.url;
indicatorPath.filtersApplied += filterResults.filtersApplied?foslvl2.length:0; indicatorPath.filtersApplied += filterResults.filtersApplied ? foslvl2.length : 0;
} }
} }
if((foslvl1 && foslvl1.length > 0) || (foslvl2 && foslvl2.length > 0)){ if ((foslvl1 && foslvl1.length > 0) || (foslvl2 && foslvl2.length > 0)) {
filterSubtitleText.push( "Field of Science: " + foslvl1.join(', ') + ( foslvl1.length > 0 && foslvl2.length > 0? ', ': '') + foslvl2.join(", ") ) ; filterSubtitleText.push("Field of Science: " + foslvl1.join(', ') + (foslvl1.length > 0 && foslvl2.length > 0 ? ', ' : '') + foslvl2.join(", "));
}
//For numbers
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id));
}
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name));
}
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName));
} }
if (indicatorPath.parameters) { if (indicatorPath.parameters) {
Object.keys(indicatorPath.parameters).forEach(key => { Object.keys(indicatorPath.parameters).forEach(key => {
@ -481,21 +436,22 @@ export class IndicatorUtils {
//if there is a parameter that is filtered and the value of the parameter changes, count the filter as applied //if there is a parameter that is filtered and the value of the parameter changes, count the filter as applied
indicatorPath.filtersApplied++; indicatorPath.filtersApplied++;
} }
if (key == "index_id") {
replacedValue = stakeholder.index_id;
}
if (key == "index_name") {
replacedValue = stakeholder.index_name;
}
if (key == "index_shortName") {
replacedValue = stakeholder.index_shortName.toLowerCase();
}
if (key == "subtitle" && filterSubtitleText.length > 0) { if (key == "subtitle" && filterSubtitleText.length > 0) {
replacedValue = replacedValue + (replacedValue.length > 0 ? ' - ':'') + ' Active filters: ('+filterSubtitleText.join(", ") + ')'; replacedValue = replacedValue + (replacedValue.length > 0 ? ' - ' : '') + ' Active filters: (' + filterSubtitleText.join(", ") + ')';
} }
replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue) replacedUrl = replacedUrl.split(ChartHelper.prefix + key + ChartHelper.suffix).join(replacedValue)
}); });
} }
//For numbers
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id));
}
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_name' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_name' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_name));
}
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_shortName' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_shortName));
}
return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl);
} }
@ -574,7 +530,7 @@ export class IndicatorUtils {
/*Chart with proper json object*/ /*Chart with proper json object*/
//apply the filter in any select fields //apply the filter in any select fields
for (let select of queries["query"]["select"]) { for (let select of queries["query"]["select"]) {
let filterString = IndicatorFilterUtils.getFilter(select["field"], filterType,filterValue); let filterString = IndicatorFilterUtils.getFilter(select["field"], filterType, filterValue);
if (filterString) { if (filterString) {
let filter = JSON.parse(filterString); let filter = JSON.parse(filterString);
//check if filter already exists //check if filter already exists
@ -598,11 +554,11 @@ export class IndicatorUtils {
filterApplied = true; filterApplied = true;
} else if (filterType == "start_year" || filterType == "end_year") { } else if (filterType == "start_year" || filterType == "end_year") {
//if has date filter already //if has date filter already
if (filterType == "start_year" && parseInt(filterValue) > parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) { // if (filterType == "start_year" && parseInt(filterValue) > parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) {
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue; queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
} else if (filterType == "end_year" && parseInt(filterValue) < parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) { // } else if (filterType == "end_year" && parseInt(filterValue) < parseInt(queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0])) {
queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue; queries["query"]["filters"][filterposition.filter]['groupFilters'][filterposition.groupFilter]["values"][0] = filterValue;
} // }
filterApplied = true; filterApplied = true;
} }
} else { } else {
@ -636,21 +592,19 @@ export class IndicatorUtils {
return values.length > 1; return values.length > 1;
} }
generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type: IndicatorType, addParameters: boolean = true): Indicator { generateIndicatorByForm(form: any, indicatorPaths: IndicatorPath[], type: IndicatorType): Indicator {
let indicator: Indicator = new Indicator(form.name, form.description, form.additionalDescription, type, let indicator: Indicator = new Indicator(form.name, form.description, form.additionalDescription, type,
form.width, form.height, form.visibility, indicatorPaths, form.defaultId); form.width, form.height, form.visibility, indicatorPaths, form.defaultId);
indicator._id = form._id; indicator._id = form._id;
form.indicatorPaths.forEach((indicatorPath, index) => { form.indicatorPaths.forEach((indicatorPath, index) => {
indicator.indicatorPaths[index].type = indicatorPath.type; indicator.indicatorPaths[index].type = indicatorPath.type;
indicator.indicatorPaths[index].format = indicatorPath.format; indicator.indicatorPaths[index].format = indicatorPath.format;
if (addParameters) { indicatorPath.parameters.forEach(parameter => {
indicatorPath.parameters.forEach(parameter => { indicator.indicatorPaths[index].parameters[parameter.key] = parameter.value;
indicator.indicatorPaths[index].parameters[parameter.key] = parameter.value; if (parameter.key === 'type') {
if (parameter.key === 'type') { indicator.indicatorPaths[index].type = parameter.value;
indicator.indicatorPaths[index].type = parameter.value; }
} });
});
}
}); });
return indicator; return indicator;
} }
@ -664,6 +618,7 @@ export class IndicatorUtils {
let chart = JSON.parse(indicatorPath.chartObject); let chart = JSON.parse(indicatorPath.chartObject);
this.parameterizeDefaultQuery(chart, indicatorPath, stakeholder); this.parameterizeDefaultQuery(chart, indicatorPath, stakeholder);
this.extractStakeHolders(chart, indicatorPath, stakeholder); this.extractStakeHolders(chart, indicatorPath, stakeholder);
this.addProfile(indicatorPath);
indicatorPath.chartObject = JSON.stringify(chart); indicatorPath.chartObject = JSON.stringify(chart);
if (!jsonPath || jsonPath.length == 0 || (jsonPath.length == 1 && jsonPath[0] == "")) { if (!jsonPath || jsonPath.length == 0 || (jsonPath.length == 1 && jsonPath[0] == "")) {
indicatorPath.jsonPath = ["data", "0", "0", "0"]; indicatorPath.jsonPath = ["data", "0", "0", "0"];
@ -723,6 +678,7 @@ export class IndicatorUtils {
this.extractStakeHolders(chart, indicatorPath, stakeholder); this.extractStakeHolders(chart, indicatorPath, stakeholder);
this.extractStartYear(chart, indicatorPath); this.extractStartYear(chart, indicatorPath);
this.extractEndYear(chart, indicatorPath); this.extractEndYear(chart, indicatorPath);
this.addProfile(indicatorPath);
indicatorPath.chartObject = JSON.stringify(chart); indicatorPath.chartObject = JSON.stringify(chart);
} }
} else if (source === 'old') { } else if (source === 'old') {
@ -802,11 +758,11 @@ export class IndicatorUtils {
for (let filter of query["query"]["filters"]) { for (let filter of query["query"]["filters"]) {
for (let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
//ignore field No Of Funders //ignore field No Of Funders
let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder, indicatorPath.parameters); let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder);
if(replacedValue) { // don't proceed in replacement if no replaced value matches if (replacedValue) { // don't proceed in replacement if no replaced value matches
if ((gfilter["field"].indexOf(" funder") != -1 && gfilter["field"].indexOf(" funders") == -1 ) || if ((gfilter["field"].indexOf(" funder") != -1 && gfilter["field"].indexOf(" funders") == -1) ||
(gfilter["field"].indexOf(".funder") != -1) || (gfilter["field"].indexOf(".funder") != -1) ||
(gfilter["field"].indexOf(".funder.id") != -1)) { (gfilter["field"].indexOf(".funder.id") != -1)) {
gfilter["values"][0] = replacedValue; gfilter["values"][0] = replacedValue;
} }
} }
@ -828,10 +784,10 @@ export class IndicatorUtils {
} }
for (let filter of query["query"]["filters"]) { for (let filter of query["query"]["filters"]) {
for (let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder, indicatorPath.parameters); let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder);
if(replacedValue) { // don't proceed in replacement if no replaced value matches if (replacedValue) { // don't proceed in replacement if no replaced value matches
if ((gfilter["field"].indexOf(".context.name") != -1) if ((gfilter["field"].indexOf(".context.name") != -1)
|| (gfilter["field"].indexOf(".context.id") != -1)) { || (gfilter["field"].indexOf(".context.id") != -1)) {
gfilter["values"][0] = replacedValue; gfilter["values"][0] = replacedValue;
} }
} }
@ -855,10 +811,10 @@ export class IndicatorUtils {
} }
for (let filter of query["query"]["filters"]) { for (let filter of query["query"]["filters"]) {
for (let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder, indicatorPath.parameters); let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder);
if(replacedValue) { // don't proceed in replacement if no replaced value matches if (replacedValue) { // don't proceed in replacement if no replaced value matches
if ((gfilter["field"].indexOf(".organization.name") != -1)|| if ((gfilter["field"].indexOf(".organization.name") != -1) ||
(gfilter["field"].indexOf(".organization.id") != -1)) { (gfilter["field"].indexOf(".organization.id") != -1)) {
gfilter["values"][0] = replacedValue; gfilter["values"][0] = replacedValue;
} }
} }
@ -866,6 +822,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractDatasource(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractDatasource(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
// works for .datasource.name and .HostedBy datasource // works for .datasource.name and .HostedBy datasource
// and .datasource.id // and .datasource.id
@ -881,10 +838,10 @@ export class IndicatorUtils {
} }
for (let filter of query["query"]["filters"]) { for (let filter of query["query"]["filters"]) {
for (let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder, indicatorPath.parameters); let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder);
if(replacedValue) { // don't proceed in replacement if no replaced value matches if (replacedValue) { // don't proceed in replacement if no replaced value matches
if ((gfilter["field"].indexOf(".datasource.name") != -1 || gfilter["field"].indexOf(".HostedBy datasource") != -1)|| if ((gfilter["field"].indexOf(".datasource.name") != -1 || gfilter["field"].indexOf(".HostedBy datasource") != -1) ||
(gfilter["field"].indexOf(".datasource.id") != -1) || (gfilter["field"].indexOf(".hostedby") != -1)) { (gfilter["field"].indexOf(".datasource.id") != -1) || (gfilter["field"].indexOf(".hostedby") != -1)) {
gfilter["values"][0] = replacedValue; gfilter["values"][0] = replacedValue;
} }
} }
@ -892,6 +849,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractResearcher(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractResearcher(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
// works for .orcid // works for .orcid
if (stakeholder.type != "researcher") { if (stakeholder.type != "researcher") {
@ -906,9 +864,9 @@ export class IndicatorUtils {
} }
for (let filter of query["query"]["filters"]) { for (let filter of query["query"]["filters"]) {
for (let gfilter of filter["groupFilters"]) { for (let gfilter of filter["groupFilters"]) {
let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder, indicatorPath.parameters); let replacedValue = this.replaceIndexValues(gfilter["values"][0], stakeholder);
if(replacedValue) { // don't proceed in replacement if no replaced value matches if (replacedValue) { // don't proceed in replacement if no replaced value matches
if ((gfilter["field"].indexOf(".orcid") != -1 )) { if ((gfilter["field"].indexOf(".orcid") != -1)) {
gfilter["values"][0] = replacedValue; gfilter["values"][0] = replacedValue;
} }
} }
@ -916,19 +874,18 @@ export class IndicatorUtils {
} }
} }
} }
private replaceIndexValues(currentValue, stakeholder, parameters ){
if(currentValue == stakeholder.index_name){ private replaceIndexValues(currentValue, stakeholder) {
parameters["index_name"] = stakeholder.index_name; if (currentValue == stakeholder.index_name) {
return ChartHelper.prefix + "index_name" + ChartHelper.suffix; return ChartHelper.prefix + "index_name" + ChartHelper.suffix;
}else if(currentValue == stakeholder.index_id){ } else if (currentValue == stakeholder.index_id) {
parameters["index_id"] = stakeholder.index_id;
return ChartHelper.prefix + "index_id" + ChartHelper.suffix; return ChartHelper.prefix + "index_id" + ChartHelper.suffix;
}else if(currentValue == stakeholder.index_shortName) { } else if (currentValue == stakeholder.index_shortName) {
parameters["index_shortName"] = stakeholder.index_shortName;
return ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; return ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
} }
} }
private extractStartYear(obj, indicatorPath: IndicatorPath) { private extractStartYear(obj, indicatorPath: IndicatorPath) {
let start_year; let start_year;
for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
@ -965,6 +922,10 @@ export class IndicatorUtils {
} }
} }
private addProfile(indicatorPath: IndicatorPath) {
indicatorPath.parameters['statsProfile'] = null;
}
private parameterizeDefaultQuery(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private parameterizeDefaultQuery(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
let name = ""; let name = "";
for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) {
@ -991,13 +952,10 @@ export class IndicatorUtils {
for (let i of index) { for (let i of index) {
if (name.split('.').length > 3 && name.split('.')[3] == "id") { if (name.split('.').length > 3 && name.split('.')[3] == "id") {
parameters[i] = ChartHelper.prefix + "index_id" + ChartHelper.suffix; parameters[i] = ChartHelper.prefix + "index_id" + ChartHelper.suffix;
indicatorPath.parameters["index_id"] = stakeholder.index_id;
} else if (name.split('.').length > 3 && name.split('.')[3] == "shortname") { } else if (name.split('.').length > 3 && name.split('.')[3] == "shortname") {
parameters[i] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix; parameters[i] = ChartHelper.prefix + "index_shortName" + ChartHelper.suffix;
indicatorPath.parameters["index_shortName"] = stakeholder.index_shortName.toLowerCase();
} else if (name.split('.').length > 3 && name.split('.')[3] == "name") { } else if (name.split('.').length > 3 && name.split('.')[3] == "name") {
parameters[i] = ChartHelper.prefix + "index_name" + ChartHelper.suffix; parameters[i] = ChartHelper.prefix + "index_name" + ChartHelper.suffix;
indicatorPath.parameters["index_name"] = stakeholder.index_name;
} }
} }
} }

View File

@ -1,6 +1,6 @@
import {SafeResourceUrl} from "@angular/platform-browser"; import {SafeResourceUrl} from "@angular/platform-browser";
import {properties} from "../../../../environments/environment";
import {Session, User} from "../../login/utils/helper.class"; import {Session, User} from "../../login/utils/helper.class";
import {StringUtils} from "../../utils/string-utils.class";
export const ChartHelper = { export const ChartHelper = {
prefix: "((__", prefix: "((__",
@ -37,6 +37,7 @@ export class Stakeholder {
isUpload: boolean = false; isUpload: boolean = false;
description: string; description: string;
topics: any[]; topics: any[];
copy: boolean = true;
details?: any; details?: any;
constructor(_id: string, type: StakeholderType, index_id: string, index_name: string, index_shortName: string, alias: string, visibility: Visibility, logoUrl: string, defaultId: string = null, description: string = null) { constructor(_id: string, type: StakeholderType, index_id: string, index_name: string, index_shortName: string, alias: string, visibility: Visibility, logoUrl: string, defaultId: string = null, description: string = null) {
@ -50,8 +51,20 @@ export class Stakeholder {
this.visibility = visibility; this.visibility = visibility;
this.logoUrl = logoUrl; this.logoUrl = logoUrl;
this.description = description; this.description = description;
this.copy = !!this.defaultId && this.defaultId !== '-1';
this.topics = []; this.topics = [];
} }
static checkIsUpload(response: Stakeholder | Stakeholder[]): any | any[] {
if (Array.isArray(response)) {
response.forEach(value => {
value.isUpload = value.logoUrl && !StringUtils.isValidUrl(value.logoUrl);
});
} else {
response.isUpload = response.logoUrl && !StringUtils.isValidUrl(response.logoUrl);
}
return response;
}
} }
export class StakeholderInfo extends Stakeholder { export class StakeholderInfo extends Stakeholder {
@ -172,6 +185,7 @@ export class Indicator {
visibility: Visibility; visibility: Visibility;
defaultId: string; defaultId: string;
indicatorPaths: IndicatorPath[]; indicatorPaths: IndicatorPath[];
activePath: number = 0;
overlay: Overlay = false; overlay: Overlay = false;
constructor(name: string, description: string, additionalDescription:string, type: IndicatorType, width: IndicatorSize,height: IndicatorSize, visibility: Visibility, indicatorPaths: IndicatorPath[], defaultId: string = null) { constructor(name: string, description: string, additionalDescription:string, type: IndicatorType, width: IndicatorSize,height: IndicatorSize, visibility: Visibility, indicatorPaths: IndicatorPath[], defaultId: string = null) {
@ -282,7 +296,7 @@ export class IndicatorFilterUtils {
} }
static getFieldForTable(field, table){ static getFieldForTable(field, table){
if(["publication", "software", "dataset", "other", "result"].indexOf(table)!=-1 && IndicatorFilterUtils.filteredFields[field]["result"]){ if(["publication", "software", "dataset", "other", "result"].indexOf(table)!=-1 && IndicatorFilterUtils.filteredFields[field]["result"]){
return IndicatorFilterUtils.filteredFields[field]["result"]; return IndicatorFilterUtils.filteredFields[field]["result"].replace("result.",table + ".");
}else{ }else{
return IndicatorFilterUtils.filteredFields[field][table]; return IndicatorFilterUtils.filteredFields[field][table];
} }

View File

@ -50,10 +50,9 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
selectedFromAndToValues: "" selectedFromAndToValues: ""
}; };
rangeFilter: RangeFilterComponent; rangeFilter: RangeFilterComponent;
minYear = Dates.currentYear - 20;
maxYear = Dates.currentYear;
public numberResults: Map<string, number> = new Map<string, number>(); public numberResults: Map<string, number> = new Map<string, number>();
public chartsActiveType: Map<string, IndicatorPath> = new Map<string, IndicatorPath>();
public currentYear = new Date().getFullYear();
public clipboard; public clipboard;
/** Services */ /** Services */
@ -179,12 +178,12 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
protected validateYearRange(navigateTo: boolean = false) { protected validateYearRange(navigateTo: boolean = false) {
let validYears = true; let validYears = true;
if (this.periodFilter.selectedToValue && (this.periodFilter.selectedToValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedToValue, Dates.currentYear - 20, Dates.currentYear))) { if (this.periodFilter.selectedToValue && (this.periodFilter.selectedToValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedToValue, this.minYear, this.maxYear))) {
this.periodFilter.selectedToValue = Dates.currentYear + ""; this.periodFilter.selectedToValue = this.maxYear + "";
validYears = false; validYears = false;
} }
if (this.periodFilter.selectedFromValue && (this.periodFilter.selectedFromValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedFromValue, Dates.currentYear - 20, Dates.currentYear))) { if (this.periodFilter.selectedFromValue && (this.periodFilter.selectedFromValue.length == 0 || !Dates.isValidYear(this.periodFilter.selectedFromValue, this.minYear, this.maxYear))) {
this.periodFilter.selectedFromValue = Dates.currentYear - 20 + ""; this.periodFilter.selectedFromValue = this.minYear + "";
validYears = false; validYears = false;
} }
if (this.periodFilter.selectedFromValue && this.periodFilter.selectedFromValue.length && this.periodFilter.selectedToValue && this.periodFilter.selectedToValue.length > 0 && parseInt(this.periodFilter.selectedFromValue, 10) > parseInt(this.periodFilter.selectedToValue, 10)) { if (this.periodFilter.selectedFromValue && this.periodFilter.selectedFromValue.length && this.periodFilter.selectedToValue && this.periodFilter.selectedToValue.length > 0 && parseInt(this.periodFilter.selectedFromValue, 10) > parseInt(this.periodFilter.selectedToValue, 10)) {
@ -208,19 +207,23 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
} }
protected setIndicators() { protected setIndicators() {
this.activeSubCategory.numbers = this.activeSubCategory.numbers.filter(section => section.indicators.length > 0);
this.activeSubCategory.charts = this.activeSubCategory.charts.filter(section => section.indicators.length > 0);
this.periodFilter.selectedFromAndToValues = (this.periodFilter.selectedFromValue || this.periodFilter.selectedToValue ? ((this.periodFilter.selectedFromValue && !this.periodFilter.selectedToValue ? "From " : "") + (!this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? "Until " : "") + (this.periodFilter.selectedFromValue ? this.periodFilter.selectedFromValue : "") + this.periodFilter.selectedFromAndToValues = (this.periodFilter.selectedFromValue || this.periodFilter.selectedToValue ? ((this.periodFilter.selectedFromValue && !this.periodFilter.selectedToValue ? "From " : "") + (!this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? "Until " : "") + (this.periodFilter.selectedFromValue ? this.periodFilter.selectedFromValue : "") +
(this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? " - " : "") + (this.periodFilter.selectedToValue ? this.periodFilter.selectedToValue : "")) : ""); (this.periodFilter.selectedFromValue && this.periodFilter.selectedToValue ? " - " : "") + (this.periodFilter.selectedToValue ? this.periodFilter.selectedToValue : "")) : "");
//clear numbers when filters change //clear numbers when filters change
this.numberResults.clear(); this.numberResults.clear();
let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>(); let urls: Map<string, [number, number, number][]> = new Map<string, [number, number, number][]>();
this.activeSubCategory.numbers.forEach((section, i) => { this.activeSubCategory.numbers.forEach((section, i) => {
section.indicators.forEach((number, j) => { section.indicators.forEach((number, j) => {
if (this.hasPermission(number.visibility)) { if (this.hasPermission(number.visibility)) {
let url = this.getFullUrl(number.indicatorPaths[0]); number.indicatorPaths.forEach((indicatorPath, k) => {
const pair = JSON.stringify([number.indicatorPaths[0].source, url]); let url = this.getFullUrl(indicatorPath);
const indexes = urls.get(pair) ? urls.get(pair) : []; const pair = JSON.stringify([indicatorPath.source, url]);
indexes.push([i, j]); const indexes = urls.get(pair) ? urls.get(pair) : [];
urls.set(pair, indexes); indexes.push([i, j, k]);
urls.set(pair, indexes);
})
} }
}); });
}); });
@ -229,10 +232,10 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
let activeSubcategory = this.activeSubCategory._id; let activeSubcategory = this.activeSubCategory._id;
this.subscriptions.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(pair[0]), pair[1]).subscribe(response => { this.subscriptions.push(this.statisticsService.getNumbers(this.indicatorUtils.getSourceType(pair[0]), pair[1]).subscribe(response => {
if(activeSubcategory === this.activeSubCategory._id) { if(activeSubcategory === this.activeSubCategory._id) {
indexes.forEach(([i, j]) => { indexes.forEach(([i, j, k]) => {
if( this.activeSubCategory?.numbers[i]?.indicators[j]) { if( this.activeSubCategory?.numbers[i]?.indicators[j]) {
let result = JSON.parse(JSON.stringify(response)); let result = JSON.parse(JSON.stringify(response));
this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[k].jsonPath.forEach(jsonPath => {
if (result) { if (result) {
result = result[jsonPath]; result = result[jsonPath];
} }
@ -245,7 +248,7 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
} else { } else {
result = 0; result = 0;
} }
this.numberResults.set(i + '-' + j, result); this.numberResults.set(i + '-' + j + '-' + k, result);
} }
}); });
} }
@ -253,10 +256,9 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
}); });
this.activeSubCategory.charts.forEach((section, i) => { this.activeSubCategory.charts.forEach((section, i) => {
section.indicators.forEach((indicator, j) => { section.indicators.forEach((indicator, j) => {
if (indicator.indicatorPaths.length > 0) { indicator.indicatorPaths.forEach((indicatorPath, k) => {
indicator.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[0]); indicator.indicatorPaths[k].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[k]);
this.chartsActiveType.set(i + '-' + j, indicator.indicatorPaths[0]); });
}
}); });
}); });
if (this.cdr && !(this.cdr as ViewRef).destroyed) { if (this.cdr && !(this.cdr as ViewRef).destroyed) {
@ -269,10 +271,12 @@ export abstract class MonitorIndicatorStakeholderBaseComponent extends Indicator
this.indicatorUtils.getChartUrl(indicatorPath.source, this.getFullUrl(indicatorPath))); this.indicatorUtils.getChartUrl(indicatorPath.source, this.getFullUrl(indicatorPath)));
} }
public setActiveChart(i: number, j: number, type: string) { public getActiveIndicatorPath(indicator: Indicator) {
let activeChart = this.activeSubCategory.charts[i].indicators[j].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0]; if(indicator.activePath) {
activeChart.safeResourceUrl = this.getUrlByStakeHolder(activeChart); return indicator.indicatorPaths[indicator.activePath];
this.chartsActiveType.set(i + '-' + j, activeChart); } else {
return indicator.indicatorPaths[0];
}
} }
public filter() { public filter() {

View File

@ -1,17 +1,21 @@
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http"; import {HttpClient} from "@angular/common/http";
import {BehaviorSubject, from, Observable, Subscriber} from "rxjs"; import {BehaviorSubject, from, Observable, Subscriber} from "rxjs";
import {Indicator, Section, Stakeholder, StakeholderInfo, Visibility} from "../entities/stakeholder"; import {Indicator, Section, Stakeholder, StakeholderInfo, SubCategory, Visibility} from "../entities/stakeholder";
import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {map} from "rxjs/operators"; import {map} from "rxjs/operators";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {CustomOptions} from "../../services/servicesUtils/customOptions.class"; import {CustomOptions} from "../../services/servicesUtils/customOptions.class";
import {StringUtils} from "../../utils/string-utils.class";
export interface Reorder { export interface SectionInfo {
action: 'moved' | 'added' | 'removed', id: string;
target: string, indicators: string[];
ids: string[]; }
export interface MoveIndicator {
target: string;
from: SectionInfo;
to: SectionInfo;
} }
@Injectable({ @Injectable({
@ -41,7 +45,7 @@ export class StakeholderService {
if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== alias || shouldUpdate) { if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== alias || shouldUpdate) {
this.promise = new Promise<void>((resolve, reject) => { this.promise = new Promise<void>((resolve, reject) => {
this.sub = this.http.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(alias), CustomOptions.registryOptions()).pipe(map(stakeholder => { this.sub = this.http.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent(alias), CustomOptions.registryOptions()).pipe(map(stakeholder => {
return this.formalize(this.checkIsUpload(stakeholder)); return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder));
})).subscribe(stakeholder => { })).subscribe(stakeholder => {
this.stakeholderSubject.next(stakeholder); this.stakeholderSubject.next(stakeholder);
resolve(); resolve();
@ -53,23 +57,24 @@ export class StakeholderService {
} }
return from(this.getStakeholderAsync()); return from(this.getStakeholderAsync());
} }
getResearcherStakeholder( orcid, name, results, shouldUpdate: boolean = false): Observable<Stakeholder> {
getResearcherStakeholder(orcid, name, results, shouldUpdate: boolean = false): Observable<Stakeholder> {
if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== orcid || shouldUpdate) { if (!this.stakeholderSubject.value || this.stakeholderSubject.value.alias !== orcid || shouldUpdate) {
this.promise = new Promise<void>((resolve, reject) => { this.promise = new Promise<void>((resolve, reject) => {
this.sub = this.http.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent("researcher"), CustomOptions.registryOptions()).pipe(map(stakeholder => { this.sub = this.http.get<Stakeholder>(properties.monitorServiceAPIURL + '/stakeholder/' + encodeURIComponent("researcher"), CustomOptions.registryOptions()).pipe(map(stakeholder => {
return this.formalize(this.checkIsUpload(stakeholder)); return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder));
})).subscribe(stakeholder => { })).subscribe(stakeholder => {
stakeholder.index_id = orcid; stakeholder.index_id = orcid;
stakeholder.index_name = name; stakeholder.index_name = name;
stakeholder.name = name; stakeholder.name = name;
stakeholder.alias = orcid; stakeholder.alias = orcid;
if(results <7 && stakeholder.topics[0]?.categories[0]?.subCategories[0]){ if (results < 7 && stakeholder.topics[0]?.categories[0]?.subCategories[0]) {
stakeholder.topics[0].categories[0].subCategories[0].charts=[]; // keep only numbers - charts wont show much anyway stakeholder.topics[0].categories[0].subCategories[0].charts = []; // keep only numbers - charts wont show much anyway
} }
this.stakeholderSubject.next(stakeholder); this.stakeholderSubject.next(stakeholder);
resolve(); resolve();
}, error => { }, error => {
let stakeholder = new Stakeholder(null,"researcher", orcid,name,name,orcid,"PUBLIC", null, null,""); let stakeholder = new Stakeholder(null, "researcher", orcid, name, name, orcid, "PUBLIC", null, null, "");
this.stakeholderSubject.next(stakeholder); this.stakeholderSubject.next(stakeholder);
resolve(); resolve();
}); });
@ -89,34 +94,38 @@ export class StakeholderService {
getAlias(url: string): Observable<string[]> { getAlias(url: string): Observable<string[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder/alias', CustomOptions.registryOptions()).pipe(map(stakeholders => { return this.http.get<Stakeholder[]>(url + '/stakeholder/alias', CustomOptions.registryOptions()).pipe(map(stakeholders => {
return this.formalize(stakeholders); return HelperFunctions.copy(stakeholders);
})); }));
} }
getStakeholders(url: string, type: string = null, defaultId: string = null): Observable<(Stakeholder & StakeholderInfo)[]> { getStakeholders(url: string, type: string = null, defaultId: string = null): Observable<(Stakeholder & StakeholderInfo)[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder' + ((type) ? ('?type=' + type) : '') + ((!type && defaultId) ? ('?defaultId=' + defaultId) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => { return this.http.get<Stakeholder[]>(url + '/stakeholder' + ((type) ? ('?type=' + type) : '') + ((!type && defaultId) ? ('?defaultId=' + defaultId) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => {
return this.formalize(this.checkIsUpload(stakeholders)); return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholders));
})); }));
} }
getMyStakeholders(url: string, type: string = null): Observable<(Stakeholder & StakeholderInfo)[]> { getMyStakeholders(url: string, type: string = null): Observable<(Stakeholder & StakeholderInfo)[]> {
return this.http.get<Stakeholder[]>(url + '/my-stakeholder' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => { return this.http.get<Stakeholder[]>(url + '/my-stakeholder' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => {
return this.formalize(this.checkIsUpload(stakeholders)); return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholders));
})); }));
} }
getDefaultStakeholders(url: string, type: string = null): Observable<Stakeholder[]> { getDefaultStakeholders(url: string, type: string = null): Observable<Stakeholder[]> {
return this.http.get<Stakeholder[]>(url + '/stakeholder/default' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => { return this.http.get<Stakeholder[]>(url + '/stakeholder/default' + ((type) ? ('?type=' + type) : ''), CustomOptions.registryOptions()).pipe(map(stakeholders => {
return this.formalize(this.checkIsUpload(stakeholders)); return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholders));
})); }));
} }
buildStakeholder(url: string, stakeholder: Stakeholder): Observable<Stakeholder> { buildStakeholder(url: string, stakeholder: Stakeholder, copyId: string): Observable<Stakeholder> {
if (stakeholder.alias && stakeholder.alias.startsWith('/')) { if (stakeholder.alias && stakeholder.alias.startsWith('/')) {
stakeholder.alias = stakeholder.alias.slice(1); stakeholder.alias = stakeholder.alias.slice(1);
} }
return this.http.post<Stakeholder>(url + '/build-stakeholder', stakeholder, CustomOptions.registryOptions()).pipe(map(stakeholder => { let copy = {
return this.formalize(this.checkIsUpload(stakeholder)); stakeholder: stakeholder,
copyId: copyId
}
return this.http.post<Stakeholder>(url + '/build-stakeholder', copy, CustomOptions.registryOptions()).pipe(map(stakeholder => {
return HelperFunctions.copy(Stakeholder.checkIsUpload(stakeholder));
})); }));
} }
@ -124,43 +133,39 @@ export class StakeholderService {
return this.http.post<Visibility>(url + '/' + path.join('/') + '/change-visibility' + '?visibility=' + visibility + (propagate ? '&propagate=true' : ''), null, CustomOptions.registryOptions()); return this.http.post<Visibility>(url + '/' + path.join('/') + '/change-visibility' + '?visibility=' + visibility + (propagate ? '&propagate=true' : ''), null, CustomOptions.registryOptions());
} }
saveElement(url: string, element: any, path: string[] = []): Observable<any> { saveElement(url: string, element: any, path: string[] = [], isFull: boolean = false): Observable<any> {
if (element.alias && element.alias.startsWith('/')) { if (element.alias && element.alias.startsWith('/')) {
element.alias = element.alias.slice(1); element.alias = element.alias.slice(1);
} }
path = HelperFunctions.encodeArray(path);
return this.http.post<any>(url + ((path.length > 0) ? '/' : '') + path.join('/') + return this.http.post<any>(url + ((path.length > 0) ? '/' : '') + path.join('/') +
'/save', element, CustomOptions.registryOptions()).pipe(map(element => { '/save' + (isFull?'/full':''), element, CustomOptions.registryOptions()).pipe(map(element => {
if (path.length === 0) { if (path.length === 0) {
return this.formalize(this.checkIsUpload(element)); return HelperFunctions.copy(Stakeholder.checkIsUpload(element));
} else { } else {
return this.formalize(element); return HelperFunctions.copy(element);
} }
})); }));
} }
saveBulkElements(url: string, indicators, path: string[] = []): Observable<any> { saveBulkElements(url: string, indicators, path: string[] = []): Observable<any> {
path = HelperFunctions.encodeArray(path);
return this.http.post<any>(url + ((path.length > 0) ? '/' : '') + path.join('/') + return this.http.post<any>(url + ((path.length > 0) ? '/' : '') + path.join('/') +
'/save-bulk', indicators, CustomOptions.registryOptions()).pipe(map(element => { '/save-bulk', indicators, CustomOptions.registryOptions()).pipe(map(element => {
if (path.length === 0) { if (path.length === 0) {
return this.formalize(this.checkIsUpload(element)); return HelperFunctions.copy(Stakeholder.checkIsUpload(element));
} else { } else {
return this.formalize(element); return HelperFunctions.copy(element);
} }
})); }));
} }
saveSection(url: string, element: any, path: string[] = [], index: number = -1): Observable<Section> { saveSection(url: string, element: any, path: string[] = [], index: number = -1): Observable<Section> {
path = HelperFunctions.encodeArray(path);
return this.http.post<Section>(url + ((path.length > 0) ? '/' : '') + path.join('/') + return this.http.post<Section>(url + ((path.length > 0) ? '/' : '') + path.join('/') +
'/save/' + index, element, CustomOptions.registryOptions()).pipe(map(element => { '/save/' + index, element, CustomOptions.registryOptions()).pipe(map(element => {
return this.formalize(element); return HelperFunctions.copy(element);
})); }));
} }
deleteElement(url: string, path: string[], childrenAction: string = null): Observable<any> { deleteElement(url: string, path: string[], childrenAction: string = null): Observable<any> {
path = HelperFunctions.encodeArray(path);
let params: string = ""; let params: string = "";
if (childrenAction) { if (childrenAction) {
params = "?children=" + childrenAction; params = "?children=" + childrenAction;
@ -169,14 +174,18 @@ export class StakeholderService {
} }
reorderElements(url: string, path: string[], ids: string[]): Observable<any> { reorderElements(url: string, path: string[], ids: string[]): Observable<any> {
path = HelperFunctions.encodeArray(path);
return this.http.post<any>(url + '/' + path.join('/') + '/reorder', ids, CustomOptions.registryOptions()); return this.http.post<any>(url + '/' + path.join('/') + '/reorder', ids, CustomOptions.registryOptions());
} }
reorderIndicators(url: string, path: string[], reorder: Reorder, type: string = 'chart'): Observable<Indicator[]> { reorderIndicators(url: string, path: string[], indicators: string[]): Observable<Indicator[]> {
path = HelperFunctions.encodeArray(path); return this.http.post<Indicator[]>(url + '/' + path.join('/') + '/reorder', indicators, CustomOptions.registryOptions()).pipe(map(indicators => {
return this.http.post<Indicator[]>(url + '/' + path.join('/') + '/' + type + '/reorder', reorder, CustomOptions.registryOptions()).pipe(map(indicators => { return HelperFunctions.copy(indicators);
return this.formalize(indicators); }));
}
moveIndicator(url: string, path: string[], moveIndicator: MoveIndicator): Observable<SubCategory> {
return this.http.post<SubCategory>(url + '/' + path.join('/') + '/moveIndicator', moveIndicator, CustomOptions.registryOptions()).pipe(map(subCategory => {
return HelperFunctions.copy(subCategory);
})); }));
} }
@ -187,19 +196,4 @@ export class StakeholderService {
setStakeholder(stakeholder: Stakeholder) { setStakeholder(stakeholder: Stakeholder) {
this.stakeholderSubject.next(stakeholder); this.stakeholderSubject.next(stakeholder);
} }
private checkIsUpload(response: Stakeholder | Stakeholder[]): any | any[] {
if (Array.isArray(response)) {
response.forEach(value => {
value.isUpload = value.logoUrl && !StringUtils.isValidUrl(value.logoUrl);
});
} else {
response.isUpload = response.logoUrl && !StringUtils.isValidUrl(response.logoUrl);
}
return response;
}
private formalize(element: any) {
return HelperFunctions.copy(element);
}
} }

View File

@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import {LoginGuard} from "../../login/loginGuard.guard";
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
import {MyOrcidLinksComponent} from "./myOrcidLinks.component";
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: MyOrcidLinksComponent,
canActivate: [LoginGuard], canDeactivate: [PreviousRouteRecorder]
}
])
]
})
export class MyOrcidLinksRoutingModule { }

View File

@ -9,14 +9,15 @@ import {MyOrcidLinksComponent} from "./myOrcidLinks.component";
import {SearchResearchResultsServiceModule} from "../../services/searchResearchResultsService.module"; import {SearchResearchResultsServiceModule} from "../../services/searchResearchResultsService.module";
import {SearchMyOrcidResultsModule} from "./searchMyOrcidResults.module"; import {SearchMyOrcidResultsModule} from "./searchMyOrcidResults.module";
import {AlertModalModule} from "../../utils/modal/alertModal.module"; import {AlertModalModule} from "../../utils/modal/alertModal.module";
import {PiwikServiceModule} from "../../utils/piwik/piwikService.module"; import {MyOrcidLinksRoutingModule} from "./myOrcidLinks-routing.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, CommonModule, FormsModule,
MyOrcidLinksRoutingModule,
RouterModule, ErrorMessagesModule, RouterModule, ErrorMessagesModule,
ResultPreviewModule, SearchResearchResultsServiceModule, SearchMyOrcidResultsModule, ResultPreviewModule, SearchResearchResultsServiceModule, SearchMyOrcidResultsModule,
AlertModalModule, PiwikServiceModule AlertModalModule
], ],
declarations: [ declarations: [
MyOrcidLinksComponent MyOrcidLinksComponent

View File

@ -6,15 +6,15 @@ import {RouterModule} from '@angular/router';
import {ResultPreviewModule} from "../../utils/result-preview/result-preview.module"; import {ResultPreviewModule} from "../../utils/result-preview/result-preview.module";
import {ErrorMessagesModule} from "../../utils/errorMessages.module"; import {ErrorMessagesModule} from "../../utils/errorMessages.module";
import {searcMyOrcidResultsComponent} from "./searchMyOrcidResults.component"; import {searcMyOrcidResultsComponent} from "./searchMyOrcidResults.component";
import {OrcidModule} from "../orcid.module";
import {NoLoadPaging} from "../../searchPages/searchUtils/no-load-paging.module"; import {NoLoadPaging} from "../../searchPages/searchUtils/no-load-paging.module";
import {PagingModule} from "../../utils/paging.module"; import {PagingModule} from "../../utils/paging.module";
import {OrcidCoreModule} from "../orcid-core.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, CommonModule, FormsModule,
RouterModule, ErrorMessagesModule, RouterModule, ErrorMessagesModule,
ResultPreviewModule, OrcidModule, NoLoadPaging, PagingModule ResultPreviewModule, OrcidCoreModule, NoLoadPaging, PagingModule
], ],
declarations: [ declarations: [
searcMyOrcidResultsComponent searcMyOrcidResultsComponent

View File

@ -0,0 +1,43 @@
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 {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";
@NgModule({
imports: [
CommonModule, RouterModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule,
IconsModule, FullScreenModalModule, LogServiceModule
],
declarations: [
OrcidComponent,
OrcidWorkComponent
],
providers:[
OrcidService, ResultLandingService
],
exports: [
OrcidComponent,
OrcidWorkComponent
]
})
export class OrcidCoreModule{
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([orcid_add, orcid_bin])
}
}

View File

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import {LoginGuard} from "../login/loginGuard.guard";
import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard";
import {OrcidComponent} from './orcid.component';
@NgModule({
imports: [
RouterModule.forChild([
{ path: '', component: OrcidComponent,
canActivate: [LoginGuard],
canDeactivate: [PreviousRouteRecorder] }
])
]
})
export class OrcidRoutingModule { }

View File

@ -1,4 +1,4 @@
import {Component, Input, ViewChild} from '@angular/core'; import {ChangeDetectorRef, Component, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router"; import {ActivatedRoute, Router} from "@angular/router";
import {Subscriber, Subscription} from "rxjs"; import {Subscriber, Subscription} from "rxjs";
import {OrcidService} from "./orcid.service"; import {OrcidService} from "./orcid.service";
@ -22,88 +22,54 @@ declare var UIkit: any;
template: ` template: `
<ng-container *ngIf="pageType == 'landing' || pageType == 'search'"> <ng-container *ngIf="pageType == 'landing' || pageType == 'search'">
<span *ngIf="!putCodes || putCodes.length == 0" <span *ngIf="!putCodes || putCodes.length == 0"
(click)="currentAction='add'; saveWorkPreparation();" [ngClass]="isMobile && pageType == 'landing' ? ' uk-width-1-1' : ''"
[class.uk-disabled]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" [attr.uk-tooltip]="isMobile? 'cls: uk-invisible' : 'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[class.clickable]="!showLoading && isLoggedIn && (pids || (identifiers && identifiers.size > 0))" [title]="(noPids || !isLoggedIn) ? ((noPids) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd">
[ngClass]="isMobile && pageType == 'landing' ? ' uk-width-1-1' : ''" <span (click)="currentAction='add'; saveWorkPreparation();"
[attr.uk-tooltip]="isMobile? 'cls: uk-invisible' : 'pos: bottom; cls: uk-active uk-text-small uk-padding-small'" [class.uk-disabled]="isDisabled"
[title]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd"> [class.clickable]="!isDisabled">
<a class="uk-flex uk-flex-middle uk-button-link" <a class="uk-flex uk-flex-middle uk-button-link"
[ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : ''" [ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : ''"
[class.uk-text-bolder]="!(isMobile && pageType == 'landing')" [class.uk-text-bolder]="!(isMobile && pageType == 'landing')"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" [class.uk-text-muted]="isDisabled">
(mouseover)="hoverEvent($event)" (mouseout)="hoverEvent($event)"> <icon *ngIf="!showLoading" [class.text-orcid]="properties.environment != 'beta' && !showLoading && isLoggedIn && (pids || identifiers?.size > 0)"
<icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)" [class.uk-text-muted]="isDisabled"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" name="orcid_add" [ratio]="(isMobile && pageType == 'search') ? 0.7 : 1" visuallyHidden="add"></icon>
name="orcid_add" [ratio]="(isMobile && pageType == 'search') ? 0.7 : 1" visuallyHidden="add"></icon> <span *ngIf="showLoading" class="uk-icon"><loading
<span *ngIf="showLoading" class="uk-icon"><loading [top_margin]="false" [size]="'small'"></loading></span>
[top_margin]="false" [size]="'small'"></loading></span> <span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Claim</span>
<span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Claim</span> </a>
</a> <div *ngIf="isMobile && pageType == 'landing'" class="uk-margin-xsmall-top uk-padding uk-padding-remove-vertical uk-text-meta uk-text-xsmall"
<div *ngIf="isMobile && pageType == 'landing'" class="uk-margin-xsmall-top uk-padding uk-padding-remove-vertical uk-text-meta uk-text-xsmall" [innerHTML]="(noPids || !isLoggedIn) ? ((noPids) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd"></div>
[innerHTML]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipAdd"></div> </span>
</span> </span>
<span *ngIf="putCodes && putCodes.length > 0" <span *ngIf="putCodes && putCodes.length > 0" [ngClass]="isMobile && pageType == 'landing' ? ' uk-width-1-1' : ''"
(click)="currentAction='delete'; deleteWorks();"
[class.uk-disabled]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))"
[class.clickable]="!showLoading && isLoggedIn && (pids || (identifiers && identifiers.size > 0))"
[ngClass]="isMobile && pageType == 'landing' ? ' uk-width-1-1' : ''"
[attr.uk-tooltip]="isMobile? 'cls: uk-invisible' : 'pos: bottom; cls: uk-active uk-text-small uk-padding-small'" [attr.uk-tooltip]="isMobile? 'cls: uk-invisible' : 'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[title]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete"> [title]="(noPids || !isLoggedIn) ? ((noPids) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a class="uk-flex uk-flex-middle uk-button-link" <span (click)="currentAction='delete'; deleteWorks();"
[ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : ''" [class.uk-disabled]="isDisabled"
[class.uk-text-bolder]="!(isMobile && pageType == 'landing')" [class.clickable]="!isDisabled">
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" <a class="uk-flex uk-flex-middle uk-button-link"
(mouseover)="hoverEvent($event, 'delete')" (mouseout)="hoverEvent($event, 'delete')"> [ngClass]="isMobile && !(pageType == 'landing') ? 'uk-margin-left' : ''"
<icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)" [class.uk-text-bolder]="!(isMobile && pageType == 'landing')"
[class.uk-text-muted]="showLoading || !isLoggedIn || (!pids && (!identifiers || identifiers.size == 0))" [class.uk-text-muted]="isDisabled">
name="orcid_bin" [ratio]="(isMobile && pageType == 'search') ? 0.7 : 1" visuallyHidden="delete"></icon> <icon *ngIf="!showLoading" [class.text-orcid]="!showLoading && isLoggedIn && (pids || identifiers?.size > 0)"
<span *ngIf="showLoading" class="uk-icon"><loading [class.uk-text-muted]="isDisabled"
[top_margin]="false" [size]="'small'"></loading></span> name="orcid_bin" [ratio]="(isMobile && pageType == 'search') ? 0.7 : 1" visuallyHidden="delete"></icon>
<span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Remove</span> <span *ngIf="showLoading" class="uk-icon"><loading
</a> [top_margin]="false" [size]="'small'"></loading></span>
<div *ngIf="isMobile && pageType == 'landing'" class="uk-margin-xsmall-top uk-padding uk-padding-remove-vertical uk-text-meta uk-text-xsmall" <span [ngClass]="(isMobile && pageType == 'landing') ? 'uk-margin-small-left' : 'uk-margin-xsmall-left'">Remove</span>
[innerHTML]="((!pids && (!identifiers || identifiers.size == 0)) || !isLoggedIn) ? ((!pids && (!identifiers || identifiers.size == 0)) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete"></div> </a>
<div *ngIf="isMobile && pageType == 'landing'" class="uk-margin-xsmall-top uk-padding uk-padding-remove-vertical uk-text-meta uk-text-xsmall"
[innerHTML]="(noPids || !isLoggedIn) ? ((noPids) ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete"></div>
</span>
</span> </span>
<!-- Old 'remove' code -->
<!-- <span *ngIf="putCodes && putCodes.length > 0"
[attr.uk-tooltip]="'pos: bottom; cls: uk-active uk-text-small uk-padding-small'"
[title]="(!pids || !isLoggedIn) ? (!pids ? tooltipNoPid : tooltipNoLoggedInUser) : tooltipDelete">
<a *ngIf="!showLoading" (click)="currentAction='delete'; deleteWorks();"
class="uk-icon-button uk-icon landing-action-button landing-action-button-orcid"
[class.uk-disabled]="showLoading || !isLoggedIn || !pids"
(mouseover)="hoverEvent($event, 'delete')" (mouseout)="hoverEvent($event, 'delete')">
<icon *ngIf="!hoverDelete" name="orcid_bin" ratio="1.1" visuallyHidden="delete"></icon>
<icon *ngIf="hoverDelete" name="delete_outline" class="uk-text-danger" visuallyHidden="delete"></icon>
</a>
<span *ngIf="showLoading" class="uk-icon icon-button uk-icon-button-small"><loading
[top_margin]="false" [size]="'small'"></loading></span>
</span> -->
</ng-container> </ng-container>
<modal-alert *ngIf="!isMobile" #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()"> <modal-alert *ngIf="!isMobile" #grantModal [overflowBody]=false (alertOutput)="openGrantWindow()">
<div> <div>
<div>{{requestGrantMessage}}</div> <div>{{requestGrantMessage}}</div>
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closeGrantModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <button (click)="openGrantWindow()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Grant OpenAIRE</span>-->
<!-- </button>-->
<!--&lt;!&ndash; <button (click)="openGrantWindow()" type="submit"&ndash;&gt;-->
<!--&lt;!&ndash; class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left orcid-button">&ndash;&gt;-->
<!--&lt;!&ndash; <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="">{{" "}}&ndash;&gt;-->
<!--&lt;!&ndash; <span>Create or Connect your ORCID iD</span>&ndash;&gt;-->
<!--&lt;!&ndash; </button>&ndash;&gt;-->
<!-- </div>-->
</div> </div>
</modal-alert> </modal-alert>
@ -119,7 +85,7 @@ declare var UIkit: any;
<ng-container *ngIf="!showOnlyUpdateButton"> <ng-container *ngIf="!showOnlyUpdateButton">
<span class="uk-margin-bottom uk-flex uk-flex-middle uk-flex-center"> <span class="uk-margin-bottom uk-flex uk-flex-middle uk-flex-center">
<span>ORCID&#160;</span> <span>ORCID&#160;</span>
<img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="" loading="lazy"> <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="ORCID logo" loading="lazy">
<span>&#160;ACTIONS</span> <span>&#160;ACTIONS</span>
</span> </span>
@ -292,18 +258,6 @@ declare var UIkit: any;
instead. instead.
</div> </div>
</div> </div>
<!-- <div class="uk-margin-medium-top uk-align-right">-->
<!-- <button (click)="closePropagationModal()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- <button (click)="confirmedPropagation()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Continue</span>-->
<!-- </button>-->
<!-- </div>-->
</modal-alert> </modal-alert>
<fs-modal #propagationFsModal classTitle="uk-tile-default uk-border-bottom"> <fs-modal #propagationFsModal classTitle="uk-tile-default uk-border-bottom">
@ -369,9 +323,6 @@ export class OrcidWorkComponent {
public hasConsent: boolean = false; public hasConsent: boolean = false;
public currentAction: string = ""; public currentAction: string = "";
public hoverAdd: boolean = false;
public hoverDelete: boolean = false;
public properties: EnvProperties = properties; public properties: EnvProperties = properties;
public openaireEntities = OpenaireEntities; public openaireEntities = OpenaireEntities;
@ -379,7 +330,8 @@ export class OrcidWorkComponent {
private _router: Router, private _router: Router,
private orcidService: OrcidService, private orcidService: OrcidService,
private resultLandingService: ResultLandingService, 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') { if (typeof document !== 'undefined') {
this.tokenUrl = properties.orcidTokenURL this.tokenUrl = properties.orcidTokenURL
+ "client_id=" + properties.orcidClientId + "client_id=" + properties.orcidClientId
@ -391,24 +343,26 @@ export class OrcidWorkComponent {
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { if(this.properties.environment != 'beta') {
if (user) { this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.isLoggedIn = true; if (user) {
if (!this.givenPutCode) { this.isLoggedIn = true;
this.getPutCode(); if (!this.givenPutCode) {
this.getPutCode();
}
} else {
this.isLoggedIn = false;
} }
} else { }, error => {
this.isLoggedIn = false; 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( this.subscriptions.push(this.orcidService.getPutCode(this.pids).subscribe(
putCodes => { putCodes => {
this.putCodes = putCodes; this.putCodes = putCodes;
this.cdr.markForCheck();
// this.cdr.detectChanges();
}, error => { }, error => {
} }
@ -572,7 +528,9 @@ export class OrcidWorkComponent {
this.putCodes.push("" + response['put-code']); this.putCodes.push("" + response['put-code']);
this.creationDates.push(response['created-date']['value']); this.creationDates.push(response['created-date']['value']);
this.updateDates.push(response['last-modified-date']['value']); this.updateDates.push(response['last-modified-date']['value']);
this.cdr.markForCheck();
// this.cdr.detectChanges();
// this.closeGrantModal(); // this.closeGrantModal();
// this.message = "You have successfully added work with pids: "+this.pids+" in your ORCID record!"; // 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!"; this.message = "You have successfully added work \"" + this.resultTitle + "\" in your ORCID record!";
@ -748,6 +706,8 @@ export class OrcidWorkComponent {
deletedAll = false; deletedAll = false;
} else { } else {
this.putCodes.splice(i, 1); this.putCodes.splice(i, 1);
this.cdr.markForCheck();
// this.cdr.detectChanges();
this.creationDates.splice(i, 1); this.creationDates.splice(i, 1);
this.updateDates.splice(i, 1); this.updateDates.splice(i, 1);
// this.works.splice(i, 1); // this.works.splice(i, 1);
@ -894,13 +854,18 @@ export class OrcidWorkComponent {
} }
this.showLoading = false; this.showLoading = false;
} }
get tooltipBETA() {
// return "Login to the production environment to add works to your <span class=\"text-orcid\">ORCID</span> record";
return "Add or delete a work from your <span class=\"text-orcid\">ORCID</span> record. This feature is not available on BETA.";
}
get tooltipAdd() { get tooltipAdd() {
return "Add this work to your <span class=\"text-orcid\">ORCID</span> record" + ((properties.environment == "beta") ? ". The action will affect your real ORCID iD." : ""); return (properties.environment == "beta") ? this.tooltipBETA : ("Add this work to your <span class=\"text-orcid\">ORCID</span> record" + ((properties.environment == "test") ? ". The action will affect your real ORCID iD." : ""));
} }
get tooltipDelete() { get tooltipDelete() {
return "Delete this work from your <span class=\"text-orcid\">ORCID</span> record" + ((properties.environment == "beta") ? ". The action will affect your real ORCID iD." : ""); return "Delete this work from your <span class=\"text-orcid\">ORCID</span> record" + ((properties.environment == "test") ? ". The action will affect your real ORCID iD." : "");
} }
get tooltipNoPid() { get tooltipNoPid() {
@ -908,16 +873,14 @@ export class OrcidWorkComponent {
} }
get tooltipNoLoggedInUser() { get tooltipNoLoggedInUser() {
return "Add or delete a work from your <span class=\"text-orcid\">ORCID</span> record. Please log in first." return (properties.environment == "beta") ? this.tooltipBETA : "Add or delete a work from your <span class=\"text-orcid\">ORCID</span> record. Please log in first."
} }
hoverEvent($event, action: string = "add") { get isDisabled() {
if (action == "add") { return (this.properties.environment == 'beta' || this.showLoading || !this.isLoggedIn || (!this.pids && (!this.identifiers || this.identifiers.size == 0)));
this.hoverAdd = $event.type == "mouseover"; }
this.hoverDelete = false;
} else if (action == "delete") { get noPids() {
this.hoverDelete = $event.type == "mouseover"; return (!this.pids && (!this.identifiers || this.identifiers.size == 0));
this.hoverAdd = false;
}
} }
} }

View File

@ -1,45 +1,15 @@
import {NgModule} from '@angular/core'; 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 {IconsService} from "../utils/icons/icons.service";
import {orcid_add, orcid_bin} from "../utils/icons/icons"; import {orcid_add, orcid_bin} from "../utils/icons/icons";
import {FullScreenModalModule} from "../utils/modal/full-screen-modal/full-screen-modal.module"; import {OrcidRoutingModule} from "./orcid-routing.module";
import {LogServiceModule} from "../utils/log/LogService.module"; import {OrcidCoreModule} from "./orcid-core.module";
import {OrcidComponent} from "./orcid.component";
@NgModule({ @NgModule({
imports: [ imports: [OrcidCoreModule, OrcidRoutingModule],
CommonModule, RouterModule, AlertModalModule, LoadingModule, ResultLandingUtilsModule, exports: [OrcidComponent]
IconsModule, FullScreenModalModule, LogServiceModule
],
declarations: [
OrcidComponent,
OrcidWorkComponent
],
providers:[
FreeGuard, PreviousRouteRecorder,
OrcidService, ResultLandingService
],
exports: [
OrcidComponent,
OrcidWorkComponent
]
}) })
export class OrcidModule{ export class OrcidModule{
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([orcid_add, orcid_bin])
}
} }

View File

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

View File

@ -8,22 +8,23 @@ import {SearchRecommendedResultsForOrcidComponent} from './searchRecommendedResu
import {SearchResultsModule } from '../../searchPages/searchUtils/searchResults.module'; import {SearchResultsModule } from '../../searchPages/searchUtils/searchResults.module';
import {SearchFormModule} from '../../searchPages/searchUtils/searchForm.module'; import {SearchFormModule} from '../../searchPages/searchUtils/searchForm.module';
import {IsRouteEnabled} from '../../error/isRouteEnabled.guard';
import {SearchResearchResultsModule} from "../../searchPages/searchResearchResults.module"; import {SearchResearchResultsModule} from "../../searchPages/searchResearchResults.module";
import {OrcidService} from "../orcid.service"; import {OrcidService} from "../orcid.service";
import {SearchRecommendedResultsForOrcidRoutingModule} from "./searchRecommendedResultsForOrcid-routing.module";
// import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; // import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
@NgModule({ @NgModule({
imports: [ imports: [
CommonModule, FormsModule, CommonModule, FormsModule,
RouterModule, RouterModule,
SearchRecommendedResultsForOrcidRoutingModule,
SearchFormModule, SearchResearchResultsModule, SearchFormModule, SearchResearchResultsModule,
// , BreadcrumbsModule // , BreadcrumbsModule
], ],
declarations: [ declarations: [
SearchRecommendedResultsForOrcidComponent SearchRecommendedResultsForOrcidComponent
], ],
providers:[ IsRouteEnabled, OrcidService], providers:[OrcidService],
exports: [ exports: [
SearchRecommendedResultsForOrcidComponent SearchRecommendedResultsForOrcidComponent
] ]

View File

@ -6,8 +6,6 @@ import { RouterModule } from '@angular/router';
import{ReloadRoutingModule } from './reload-routing.module'; import{ReloadRoutingModule } from './reload-routing.module';
import{ReloadComponent} from './reload.component'; import{ReloadComponent} from './reload.component';
import {PreviousRouteRecorder} from '../utils/piwik/previousRouteRecorder.guard';
import {LoadingModule} from "../utils/loading/loading.module"; import {LoadingModule} from "../utils/loading/loading.module";
@NgModule({ @NgModule({
@ -19,9 +17,7 @@ import {LoadingModule} from "../utils/loading/loading.module";
declarations: [ declarations: [
ReloadComponent ReloadComponent
], ],
providers:[ providers:[],
PreviousRouteRecorder
],
exports: [ exports: [
ReloadComponent ReloadComponent
] ]

View File

@ -12,6 +12,8 @@ import {EmailService} from "../utils/email/email.service";
import {Composer} from "../utils/email/composer"; import {Composer} from "../utils/email/composer";
import {ClearCacheService} from "../services/clear-cache.service"; import {ClearCacheService} from "../services/clear-cache.service";
import {BaseComponent} from "../sharedComponents/base/base.component"; import {BaseComponent} from "../sharedComponents/base/base.component";
import {StakeholderUtils} from "../monitor-admin/utils/indicator-utils";
import {StringUtils} from "../utils/string-utils.class";
@Component({ @Component({
selector: 'role-verification', selector: 'role-verification',
@ -19,12 +21,9 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
<modal-alert #managerModal [overflowBody]="false" (alertOutput)="verifyManager()" (cancelOutput)="cancel()" <modal-alert #managerModal [overflowBody]="false" (alertOutput)="verifyManager()" (cancelOutput)="cancel()"
[okDisabled]="code.invalid || loading"> [okDisabled]="code.invalid || loading">
<div> <div>
You have been invited to join <span You have been invited to join <span class="uk-text-bold">{{name}}</span> {{(dashboard)}} Dashboard as a {{stakeholderUtils.roles.manager}}.
class="uk-text-bold">{{name}}</span> {{(service === 'monitor' ? 'Monitor' : 'Research Community')}} Dashboard
as a manager.
<span class="uk-text-primary">Fill</span> in the <span class="uk-text-primary">verification code</span>, sent to <span class="uk-text-primary">Fill</span> in the <span class="uk-text-primary">verification code</span>, sent to
your your email, to accept the invitation request.
email, to accept the invitation request.
</div> </div>
<div *ngIf="!loading" class="uk-margin-medium-top uk-flex uk-flex-center"> <div *ngIf="!loading" class="uk-margin-medium-top uk-flex uk-flex-center">
<div input [formInput]="code" class="uk-width-medium" placeholder="Verification code"> <div input [formInput]="code" class="uk-width-medium" placeholder="Verification code">
@ -36,14 +35,12 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
</div> </div>
</modal-alert> </modal-alert>
<modal-alert #memberModal [overflowBody]="false" (cancelOutput)="cancel()" <modal-alert #memberModal [overflowBody]="false" (cancelOutput)="cancel()"
(alertOutput)="verifyMember()" [okDisabled]="(code.invalid || loading) && !isMember"> (alertOutput)="verifyMember()" [okDisabled]="(code.invalid || loading)">
<div *ngIf="!isMember"> <div>
<div> <div>
You have been invited to join <span class="uk-text-bold">{{name}}</span> Monitor Dashboard as a member. You have been invited to join <span class="uk-text-bold">{{name}}</span> {{(dashboard)}} Dashboard as a {{stakeholderUtils.roles.member}}.
<span class="uk-text-primary">Fill</span> in the <span class="uk-text-primary">verification code</span>, sent <span class="uk-text-primary">Fill</span> in the <span class="uk-text-primary">verification code</span>, sent
to to your email, to accept the invitation request.
your
email, to accept the invitation request.
</div> </div>
<div *ngIf="!loading" class="uk-margin-medium-top uk-flex uk-flex-wrap uk-flex-center"> <div *ngIf="!loading" class="uk-margin-medium-top uk-flex uk-flex-wrap uk-flex-center">
<div input [formInput]="code" class="uk-width-medium" placeholder="Verification code"> <div input [formInput]="code" class="uk-width-medium" placeholder="Verification code">
@ -54,13 +51,6 @@ import {BaseComponent} from "../sharedComponents/base/base.component";
<loading></loading> <loading></loading>
</div> </div>
</div> </div>
<div *ngIf="isMember">
<div>
Welcome! You are now a member of the OpenAIRE Monitor Dashboard for the <span
class="uk-text-bold">{{name}}</span>!
From now on, you will have access to our restricted content.
</div>
</div>
</modal-alert> </modal-alert>
<modal-alert #errorModal (alertOutput)="cancel()" [overflowBody]="false"> <modal-alert #errorModal (alertOutput)="cancel()" [overflowBody]="false">
<div> <div>
@ -83,7 +73,7 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
public id: string; public id: string;
@Input() @Input()
set type(type: string) { set type(type: string) {
this._type = Role.GROUP + type; this._type = Role.GROUP + Role.mapType(type);
} }
@Input() @Input()
public name: string; public name: string;
@ -93,6 +83,10 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
public userInfoLinkPrefix = ''; public userInfoLinkPrefix = '';
@Input() @Input()
public userInfoLink = null; public userInfoLink = null;
@Input()
public relativeTo: ActivatedRoute = this._route;
@Input()
public dashboard: string = 'Research Community';
public user: User; public user: User;
public verification: any; public verification: any;
public code: UntypedFormControl; public code: UntypedFormControl;
@ -103,8 +97,8 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
@ViewChild('errorModal') errorModal: AlertModal; @ViewChild('errorModal') errorModal: AlertModal;
public error: string = null; public error: string = null;
public loading: boolean = false; public loading: boolean = false;
public isMember: boolean = false; public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
constructor(protected _route: ActivatedRoute, constructor(protected _route: ActivatedRoute,
protected _router: Router, protected _router: Router,
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
@ -115,18 +109,23 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
private cdr: ChangeDetectorRef) { private cdr: ChangeDetectorRef) {
super(); super();
} }
ngOnInit() { ngOnInit() {
this.reset(); this.reset();
} }
ngAfterViewInit() { ngAfterViewInit() {
this.init();
}
init() {
this.ngOnDestroy();
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user; this.user = user;
this.paramsSubscription = this._route.queryParams.subscribe(params => { this.paramsSubscription = this._route.queryParams.subscribe(params => {
if (params) { if (params) {
this.cdr.detectChanges(); this.cdr.detectChanges();
if(params['verify'] && !this.isMember) { if(params['verify']) {
if (this.user) { if (this.user) {
this.subscriptions.push(this.userRegistryService.getInvitation(params['verify']).subscribe(verification => { this.subscriptions.push(this.userRegistryService.getInvitation(params['verify']).subscribe(verification => {
this.verification = verification; this.verification = verification;
@ -150,54 +149,46 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
'errorCode': LoginErrorCodes.NOT_LOGIN, 'errorCode': LoginErrorCodes.NOT_LOGIN,
'redirectUrl': this._router.url 'redirectUrl': this._router.url
}, },
relativeTo: this._route relativeTo: this.relativeTo
}); });
} }
} else if(this.isMember) {
this.openMemberModal();
} }
} else { } else {
this.isMember = false;
this.cdr.detectChanges(); this.cdr.detectChanges();
} }
}); });
})); }));
} }
ngOnDestroy() { ngOnDestroy() {
super.ngOnDestroy(); super.ngOnDestroy();
if (this.paramsSubscription instanceof Subscription) { if (this.paramsSubscription instanceof Subscription) {
this.paramsSubscription.unsubscribe(); this.paramsSubscription.unsubscribe();
} }
} }
public openManagerModal() { public openManagerModal() {
this.error = null; this.error = null;
this.managerModal.okButtonLeft = false; this.managerModal.okButtonLeft = false;
this.managerModal.okButtonText = 'Accept'; this.managerModal.okButtonText = 'Accept';
this.managerModal.stayOpen = true; this.managerModal.stayOpen = true;
this.managerModal.cancelButtonText = 'Cancel'; this.managerModal.cancelButtonText = 'Cancel';
this.managerModal.alertTitle = 'Manager Invitation'; this.managerModal.alertTitle = StringUtils.capitalize(this.stakeholderUtils.roles.manager) + ' Invitation';
this.managerModal.open(); this.managerModal.open();
} }
public openMemberModal() { public openMemberModal() {
this.error = null; this.error = null;
if(this.isMember) { this.memberModal.cancelButton = true;
this.memberModal.cancelButton = false; this.memberModal.okButtonText = 'Accept';
this.memberModal.okButtonText = 'Close';
} else {
this.memberModal.cancelButton = true;
this.memberModal.okButtonText = 'Accept';
}
this.memberModal.okButtonLeft = false; this.memberModal.okButtonLeft = false;
this.memberModal.stayOpen = true; this.memberModal.stayOpen = true;
this.memberModal.cancelButtonText = 'Cancel'; this.memberModal.cancelButtonText = 'Cancel';
this.memberModal.alertTitle = 'Member Invitation'; this.memberModal.alertTitle = StringUtils.capitalize(this.stakeholderUtils.roles.member) + ' Invitation';
this.cdr.detectChanges(); this.cdr.detectChanges();
this.memberModal.open(); this.memberModal.open();
} }
public openErrorModal() { public openErrorModal() {
this.error = null; this.error = null;
this.errorModal.cancelButton = false; this.errorModal.cancelButton = false;
@ -205,27 +196,20 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
this.errorModal.alertTitle = 'Invalid URL'; this.errorModal.alertTitle = 'Invalid URL';
this.errorModal.open(); this.errorModal.open();
} }
public verifyManager() { public verifyManager() {
this.loading = true; this.loading = true;
this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value).subscribe(() => { this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value).subscribe(() => {
this.clearCacheService.clearCache('Managers updated'); this.clearCacheService.clearCache('Managers updated');
this.managerModal.cancel(); this.managerModal.cancel();
this.error = null; this.error = null;
this.userManagementService.updateUserInfo(() => { if(this.service === "irish" || this.service === "monitor") {
if (this.paramsSubscription instanceof Subscription) { this.loading = false;
this.paramsSubscription.unsubscribe(); this.userManagementService.login(properties.domain + '/admin/' + this.verification.entity);
} } else {
if(this.service === "irish") { this.subscriptions.push(this.emailService.notifyManagers(this.id, 'manager',
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',
Composer.composeEmailToInformOldManagersForTheNewOnes(this.name, this.id)).subscribe(() => { 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; this.loading = false;
window.location.href = properties.adminPortalURL + '/' + this.verification.entity; window.location.href = properties.adminPortalURL + '/' + this.verification.entity;
@ -235,49 +219,38 @@ export class RoleVerificationComponent extends BaseComponent implements OnInit,
this.loading = false; this.loading = false;
window.location.href = properties.adminPortalURL + '/' + this.verification.entity; window.location.href = properties.adminPortalURL + '/' + this.verification.entity;
} }
)); ));
}, error => { }, error => {
console.error(error); console.error(error);
this.loading = false; this.loading = false;
window.location.href = properties.adminPortalURL + '/' + this.verification.entity; window.location.href = properties.adminPortalURL + '/' + this.verification.entity;
})); }));
} }
});
}, error => { }, error => {
this.loading = false; this.loading = false;
this.error = 'The verification code is invalid'; this.error = 'The verification code is invalid';
})); }));
} }
public verifyMember() { public verifyMember() {
this.loading = true; this.loading = true;
if (!this.isMember) {
this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value, "member").subscribe(() => { this.subscriptions.push(this.userRegistryService.verify(this.verification.id, this.code.value, "member").subscribe(() => {
this.clearCacheService.clearCache('Members updated'); this.clearCacheService.clearCache('Members updated');
this.memberModal.cancel();
this.loading = false; this.loading = false;
this.error = null; this.error = null;
this.isMember = true; window.location.href = window.location.href.split('?')[0];
this.userManagementService.updateUserInfo(() => {
if (this.paramsSubscription instanceof Subscription) {
this.paramsSubscription.unsubscribe();
}
this.cancel();
});
}, error => { }, error => {
this.loading = false; this.loading = false;
this.error = 'The verification code is invalid'; this.error = 'The verification code is invalid';
})); }));
} else {
this.memberModal.cancel();
}
} }
public reset() { public reset() {
this.code = this.fb.control('', [Validators.required, Validators.pattern('^[+0-9]{6}$')]); this.code = this.fb.control('', [Validators.required, Validators.pattern('^[+0-9]{6}$')]);
} }
cancel() { cancel() {
this.isMember = false;
this._router.navigate([]); this._router.navigate([]);
} }
} }

View File

@ -34,9 +34,9 @@
</div> </div>
</div> </div>
<div class="uk-width-2-5@m uk-width-1-1@s uk-text-center uk-position-relative" uk-scrollspy-class> <div class="uk-width-2-5@m uk-width-1-1@s uk-text-center uk-position-relative" uk-scrollspy-class>
<img src="assets/common-assets/sdg/sdg-hero-img.svg" loading="lazy"> <img src="assets/common-assets/sdg/sdg-hero-img.svg" loading="lazy" alt="SDGs logo">
<div class="uk-position-bottom-left uk-card uk-card-default uk-padding"> <div class="uk-position-bottom-left uk-card uk-card-default uk-padding">
<img src="assets/common-assets/sdg/sdg-badge.png" loading="lazy" style="max-width: 215px"> <img src="assets/common-assets/sdg/sdg-badge.png" loading="lazy" style="max-width: 215px" alt="SDGs big logo">
</div> </div>
</div> </div>
</div> </div>
@ -61,7 +61,7 @@
</div> </div>
</div> </div>
<div class="uk-text-center"> <div class="uk-text-center">
<img [src]="'assets/common-assets/sdg/icons/g' + sdg.code + '.png'" alt=""> <img [src]="'assets/common-assets/sdg/icons/g' + sdg.code + '.png'" [alt]="'SDG code: '+sdg.code">
</div> </div>
<div class="uk-text-center uk-padding-small uk-background-default" style="border-radius: 0 0 4px 4px;"> <div class="uk-text-center uk-padding-small uk-background-default" style="border-radius: 0 0 4px 4px;">
<span class="uk-text-large uk-text-bold uk-margin-small-bottom">{{sdg.number == null ? '0' : sdg.number | number}}</span> <span class="uk-text-large uk-text-bold uk-margin-small-bottom">{{sdg.number == null ? '0' : sdg.number | number}}</span>

View File

@ -2,14 +2,11 @@ import {CommonModule} from "@angular/common";
import {NgModule} from "@angular/core"; import {NgModule} from "@angular/core";
import {FormsModule} from "@angular/forms"; import {FormsModule} from "@angular/forms";
import {RouterModule} from "@angular/router"; import {RouterModule} from "@angular/router";
import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard";
import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module"; import {BreadcrumbsModule} from "../utils/breadcrumbs/breadcrumbs.module";
import {RefineFieldResultsServiceModule} from "../services/refineFieldResultsService.module"; import {RefineFieldResultsServiceModule} from "../services/refineFieldResultsService.module";
import {LoadingModule} from "../utils/loading/loading.module"; import {LoadingModule} from "../utils/loading/loading.module";
import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module"; import {Schema2jsonldModule} from "../sharedComponents/schema2jsonld/schema2jsonld.module";
import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module"; import {SEOServiceModule} from "../sharedComponents/SEO/SEOService.module";
import {PiwikService} from "../utils/piwik/piwik.service";
import {SdgRoutingModule} from './sdg-routing.module'; import {SdgRoutingModule} from './sdg-routing.module';
import {SdgComponent} from './sdg.component'; import {SdgComponent} from './sdg.component';
@ -22,9 +19,7 @@ import {SdgComponent} from './sdg.component';
declarations: [ declarations: [
SdgComponent SdgComponent
], ],
providers: [ providers: [],
PreviousRouteRecorder, PiwikService
],
exports: [ exports: [
SdgComponent SdgComponent
] ]

View File

@ -23,7 +23,8 @@ import {EnvProperties} from '../../utils/properties/env-properties';
import {SEOService} from '../../sharedComponents/SEO/SEO.service'; import {SEOService} from '../../sharedComponents/SEO/SEO.service';
import {StringUtils} from '../../utils/string-utils.class'; import {StringUtils} from '../../utils/string-utils.class';
import {SearchCustomFilter} from "../searchUtils/searchUtils.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 {AdvancedField, Filter} from "../searchUtils/searchHelperClasses.class";
import {SearchResearchResultsComponent} from "../searchResearchResults.component"; import {SearchResearchResultsComponent} from "../searchResearchResults.component";
import {SearchProjectsComponent} from "../searchProjects.component"; import {SearchProjectsComponent} from "../searchProjects.component";
@ -219,9 +220,14 @@ export class SearchAllComponent {
loadAll() { loadAll() {
this.reloadTabs(); 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.parameters = Object.assign({}, queryParams);
this.keyword = (queryParams['keyword']) ? queryParams['keyword'] : (queryParams["q"] ? queryParams["q"] : (queryParams["f0"] && queryParams["f0"] == "q" && queryParams["fv0"]?queryParams["fv0"]:"")); 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); 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; active = ((["result","projects","organizations","datasources","services"]).indexOf(queryParams["active"])!= -1)?queryParams["active"]:null;
delete this.parameters['active']; delete this.parameters['active'];
} }
// if(this.activeEntity == null) {
if(this.activeEntity == null) { if (this.activeEntity == null && (!params["entity"] || params["entity"].length == 0) && (!active || this.activeEntity != active)) {
if (this.activeEntity == null && (!params["entity"] || params["entity"].length == 0)) {
if (active) { if (active) {
this.activeEntity = active; this.activeEntity = active;
if ((typeof document !== 'undefined')) { if ((typeof document !== 'undefined')) {
@ -261,7 +266,7 @@ export class SearchAllComponent {
} }
this.activeEntity = ((["result", "projects", "organizations", "datasources", "services"]).indexOf(entity) != -1) ? entity : this.getDefaultEntityToShow(); this.activeEntity = ((["result", "projects", "organizations", "datasources", "services"]).indexOf(entity) != -1) ? entity : this.getDefaultEntityToShow();
} }
} // }
if (this.activeEntity == "result") { if (this.activeEntity == "result") {
this.searchResults(); this.searchResults();
} else if (this.activeEntity == "projects") { } else if (this.activeEntity == "projects") {
@ -274,7 +279,7 @@ export class SearchAllComponent {
this.searchOrganizations(); this.searchOrganizations();
} }
this.count(); this.count();
})); // }));
})); }));
} }

View File

@ -12,7 +12,6 @@ import {SearchResearchResultsServiceModule} from '../../services/searchResearchR
import {OrganizationsServiceModule} from '../../services/organizationsService.module'; import {OrganizationsServiceModule} from '../../services/organizationsService.module';
import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module'; import {Schema2jsonldModule} from '../../sharedComponents/schema2jsonld/schema2jsonld.module';
import {PiwikServiceModule} from '../../utils/piwik/piwikService.module';
import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module'; import { SEOServiceModule } from '../../sharedComponents/SEO/SEOService.module';
import {SearchAllComponent} from "./searchAll.component"; import {SearchAllComponent} from "./searchAll.component";
import {AdvancedSearchFormModule} from "../searchUtils/advancedSearchForm.module"; import {AdvancedSearchFormModule} from "../searchUtils/advancedSearchForm.module";
@ -20,7 +19,6 @@ import {SearchResearchResultsModule} from "../searchResearchResults.module";
import {SearchProjectsModule} from "../searchProjects.module"; import {SearchProjectsModule} from "../searchProjects.module";
import {SearchOrganizationsModule} from "../searchOrganizations.module"; import {SearchOrganizationsModule} from "../searchOrganizations.module";
import {SearchDataProvidersModule} from "../searchDataProviders.module"; import {SearchDataProvidersModule} from "../searchDataProviders.module";
import {PreviousRouteRecorder} from "../../utils/piwik/previousRouteRecorder.guard";
import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module"; import {BreadcrumbsModule} from "../../utils/breadcrumbs/breadcrumbs.module";
import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module"; import {SliderTabsModule} from "../../sharedComponents/tabs/slider-tabs.module";
import {NumberRoundModule} from "../../utils/pipes/number-round.module"; import {NumberRoundModule} from "../../utils/pipes/number-round.module";
@ -31,15 +29,13 @@ import {GroupedRequestsServiceModule} from "../../services/groupedRequestsServic
CommonModule, FormsModule, RouterModule, CommonModule, FormsModule, RouterModule,
DataProvidersServiceModule, ProjectsServiceModule, DataProvidersServiceModule, ProjectsServiceModule,
SearchResearchResultsServiceModule, OrganizationsServiceModule, 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 GroupedRequestsServiceModule
], ],
declarations: [ declarations: [
SearchAllComponent SearchAllComponent
], ],
providers:[ providers:[],
PreviousRouteRecorder
],
exports: [ exports: [
SearchAllComponent SearchAllComponent
] ]

View File

@ -57,7 +57,7 @@ export class SearchDataProvidersComponent {
@Input() @Input()
set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) {
if(!Array.isArray(customFilter)) { if(!Array.isArray(customFilter)) {
this.customFilters = [customFilter]; this.customFilters = customFilter?[customFilter]:null;
}else{ }else{
this.customFilters = customFilter; 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._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( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, this.entityType, this.properties, this.refineQuery).subscribe(
res => { res => {
let filter: Filter = res[1][0]; let filter: Filter = res[2][0];
if(filter.values.length == 0) { if(filter.values.length == 0) {
filter = oldFilter; filter = oldFilter;
filter.countAllValues = 0; filter.countAllValues = 0;

View File

@ -33,6 +33,7 @@ import {RefineFieldResultsService} from "../services/refineFieldResults.service"
[includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter" [includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter"
[searchForm]="searchForm" [searchForm]="searchForm"
[sort]="false" [sort]="false"
[showRefine]="refineFields?.length > 0"
[filters]="filters" [filters]="filters"
[simpleView]="simpleView" formPlaceholderText="Search by organization name..." [simpleView]="simpleView" formPlaceholderText="Search by organization name..."
[showSwitchSearchLink]="showSwitchSearchLink" [showSwitchSearchLink]="showSwitchSearchLink"
@ -66,7 +67,7 @@ export class SearchOrganizationsComponent {
@Input() @Input()
set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) {
if(!Array.isArray(customFilter)) { if(!Array.isArray(customFilter)) {
this.customFilters = [customFilter]; this.customFilters = customFilter?[customFilter]:null;
}else{ }else{
this.customFilters = customFilter; 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._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( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "organization", this.properties, this.refineQuery).subscribe(
res => { res => {
let filter: Filter = res[1][0]; let filter: Filter = res[2][0];
if(filter.values.length == 0) { if(filter.values.length == 0) {
filter = oldFilter; filter = oldFilter;
filter.countAllValues = 0; filter.countAllValues = 0;

View File

@ -1,7 +1,6 @@
import {NgModule} from '@angular/core'; import {NgModule} from '@angular/core';
import {CommonModule} from '@angular/common'; import {CommonModule} from '@angular/common';
import {FormsModule} from '@angular/forms'; import {FormsModule} from '@angular/forms';
import {IsRouteEnabled} from '../error/isRouteEnabled.guard';
import {NewSearchPageModule} from "./searchUtils/newSearchPage.module"; import {NewSearchPageModule} from "./searchUtils/newSearchPage.module";
import {OrganizationsServiceModule} from "../services/organizationsService.module"; import {OrganizationsServiceModule} from "../services/organizationsService.module";
import {SearchOrganizationsComponent} from "./searchOrganizations.component"; import {SearchOrganizationsComponent} from "./searchOrganizations.component";

View File

@ -50,7 +50,7 @@ export class SearchProjectsComponent {
@Input() @Input()
set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) {
if(!Array.isArray(customFilter)) { if(!Array.isArray(customFilter)) {
this.customFilters = [customFilter]; this.customFilters = customFilter?[customFilter]:null;
}else{ }else{
this.customFilters = customFilter; 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._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( // this.searchFiltersSub = this._refineFieldsResultsService.getAllRefineFieldResultsByFieldName(oldFilter.filterId, "project", this.properties, this.refineQuery).subscribe(
res => { res => {
let filter: Filter = res[1][0]; let filter: Filter = res[2][0];
if(filter.values.length == 0) { if(filter.values.length == 0) {
filter = oldFilter; filter = oldFilter;
filter.countAllValues = 0; filter.countAllValues = 0;

View File

@ -87,7 +87,7 @@ export class SearchResearchResultsComponent {
@Input() @Input()
set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) {
if(!Array.isArray(customFilter)) { if(!Array.isArray(customFilter)) {
this.customFilters = [customFilter]; this.customFilters = customFilter?[customFilter]:null;
}else{ }else{
this.customFilters = customFilter; this.customFilters = customFilter;
} }

View File

@ -1,101 +1,103 @@
<ng-template #selected_filters_pills> <ng-template #selected_filters_pills>
<h1> <h1 class="uk-margin-remove">
<div class="uk-slider filters-slider" uk-slider="finite: true"> <div [class.uk-invisible]="list.children.length === 0" [class.uk-margin-top]="list.children.length > 0">
<div [class.uk-invisible]="list.children.length === 0" class="uk-position-relative"> <ul #list class="uk-grid uk-grid-small uk-flex-wrap" uk-grid>
<div class="uk-slider-container"> <ng-container *ngFor="let customFilter of customFilters">
<ul #list class="uk-slider-items uk-grid uk-grid-small uk-margin-small-right uk-flex-nowrap" style="padding-bottom: 1px"> <ng-container *ngIf="customFilter.isHiddenFilter">
<ng-container *ngFor="let customFilter of customFilters"> <li class="uk-flex uk-flex-middle">
<ng-container *ngIf="customFilter.isHiddenFilter"> <span class="uk-text-capitalize uk-label uk-label-small uk-label-search-filter uk-text-truncate target1">
<li class="uk-flex uk-flex-middle"> {{customFilter.valueName}}
<span class="uk-label uk-label-secondary uk-text-truncate"> </span>
{{customFilter.valueName}} </li>
</ng-container>
</ng-container>
<ng-container *ngIf="resultTypes && resultTypes.countSelectedValues > 0">
<ng-container *ngFor="let type of resultTypes.values; let i = index;">
<ng-container *ngIf="type.selected">
<li class="">
<span class="uk-text-capitalize uk-label uk-label-small uk-label-search-filter uk-flex uk-flex-middle target2">
<span class="uk-margin-small-right uk-width-expand uk-text-truncate">{{type.name}}</span>
<button [class.uk-disabled]="disabled" (click)="removeResultType(type.id)" class="uk-close uk-icon" [disabled]="disabled">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</li>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngIf="selectedRangeFilters > 0">
<ng-container *ngFor="let filter of rangeFilters ">
<ng-container *ngIf="filter.selectedFromAndToValues">
<li class="">
<span class="uk-text-capitalize uk-label uk-label-small uk-label-search-filter uk-flex uk-flex-middle target3">
<span class="uk-margin-small-right uk-width-expand uk-text-truncate">{{filter.selectedFromAndToValues}}</span>
<button [class.uk-disabled]="disabled" (click)="removeRangeFilter(filter)" class="uk-close uk-icon" [disabled]="disabled">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</li>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngFor="let filter of staticFilters">
<ng-container *ngIf="filter.countSelectedValues > 0">
<ng-container *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; ">
<li *ngIf="!customFilter || (customFilter.isHiddenFilter && customFilter.valueId != value.id)"
class="">
<span class="uk-text-capitalize uk-label uk-label-small uk-label-search-filter uk-flex uk-flex-middle target4">
<span
class="uk-margin-small-right uk-width-expand uk-text-truncate">
<ng-container *ngIf="filter.type && (filter.type == 'boolean' || filter.type == 'triplet') else noboolean">
<span>{{filter.title}}:
{{(value.name=='true'||value.name=='Yes')?'Yes':'No'}}
</span>
</ng-container>
<ng-template #noboolean>
<span [attr.title]="value.name" *ngIf="value.name.length > filterPillCharactersLimit">
{{value.name | slice:0:filterPillCharactersLimit}}...
</span>
<span *ngIf="value.name.length <= filterPillCharactersLimit">
{{value.name}}
</span>
</ng-template>
</span> </span>
</li> <button [class.uk-disabled]="disabled" (click)="removeFilter(value, filter)" class="uk-close uk-icon" [disabled]="disabled">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</li>
</ng-container> </ng-container>
</ng-container> </ng-container>
<ng-container *ngIf="resultTypes && resultTypes.countSelectedValues > 0"> </ng-container>
<ng-container *ngFor="let type of resultTypes.values; let i = index;"> <ng-container *ngFor="let filter of filters ">
<ng-container *ngIf="type.selected"> <ng-container *ngIf="filter.countSelectedValues > 0">
<li class=""> <ng-container *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; ">
<span class="uk-label uk-label-primary uk-flex uk-flex-middle"> <li *ngIf="!customFilters || (customFilters[0].isHiddenFilter && customFilters[0].valueId != value.id)">
<span class="uk-margin-small-right uk-width-expand uk-text-truncate">{{type.name}}</span> <span class="uk-text-capitalize uk-label uk-label-small uk-label-search-filter uk-flex uk-flex-middle target5">
<button [class.uk-disabled]="disabled" (click)="removeResultType(type.id)" class="uk-close uk-icon" [disabled]="disabled"> <span class="uk-margin-small-right uk-width-expand uk-text-truncate">
<icon name="close" flex="true" ratio="0.7"></icon> <ng-container *ngIf="filter.type && (filter.type == 'boolean' || filter.type == 'triplet') else noboolean">
</button> <span>{{filter.title}}:
</span> {{(value.name=='true'||value.name=='Yes')?'Yes':'No'}}
</li> </span>
</ng-container> </ng-container>
</ng-container> <ng-template #noboolean>
</ng-container> <span [attr.title]="value.name" *ngIf="value.name.length > filterPillCharactersLimit">
<ng-container *ngIf="selectedRangeFilters > 0"> {{value.name | slice:0:filterPillCharactersLimit}}...
<ng-container *ngFor="let filter of rangeFilters "> </span>
<ng-container *ngIf="filter.selectedFromAndToValues"> <span *ngIf="value.name.length <= filterPillCharactersLimit">
<li class="">
<span class="uk-label uk-label-primary uk-flex uk-flex-middle">
<span class="uk-margin-small-right uk-width-expand uk-text-truncate">{{filter.selectedFromAndToValues}}</span>
<button [class.uk-disabled]="disabled" (click)="removeRangeFilter(filter)" class="uk-close uk-icon" [disabled]="disabled">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</li>
</ng-container>
</ng-container>
</ng-container>
<ng-container *ngFor="let filter of staticFilters">
<ng-container *ngIf="filter.countSelectedValues > 0">
<ng-container *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; ">
<li *ngIf="!customFilter || (customFilter.isHiddenFilter && customFilter.valueId != value.id)"
class="">
<span class="uk-label uk-label-primary uk-flex uk-flex-middle">
<span
class="uk-margin-small-right uk-width-expand uk-text-truncate">
<ng-container *ngIf="filter.type && (filter.type == 'boolean' || filter.type == 'triplet') else noboolean">
<!-- *ngIf="filter.type == 'boolean'"-->
<span>{{filter.title}}:
{{(value.name=='true'||value.name=='Yes')?'Yes':'No'}}
</span>
<!-- <span *ngIf="filter.type == 'triplet'">{{value.name=='true'?'':'Not '}}{{filter.title}}</span>-->
</ng-container>
<ng-template #noboolean>
{{value.name}} {{value.name}}
</ng-template></span> </span>
<button [class.uk-disabled]="disabled" (click)="removeFilter(value, filter)" class="uk-close uk-icon" [disabled]="disabled"> </ng-template>
<icon name="close" flex="true" ratio="0.7"></icon> </span>
</button> <button [class.uk-disabled]="disabled" (click)="removeFilter(value, filter)" class="uk-close uk-icon" [disabled]="disabled">
</span> <icon name="close" flex="true" ratio="0.7"></icon>
</li> </button>
</ng-container> </span>
</ng-container> </li>
</ng-container> </ng-container>
<ng-container *ngFor="let filter of filters "> </ng-container>
<ng-container *ngIf="filter.countSelectedValues > 0"> </ng-container>
<ng-container *ngFor="let value of getSelectedValues(filter); let i = index; let end = last; "> </ul>
<li *ngIf="!customFilters || (customFilters[0].isHiddenFilter && customFilters[0].valueId != value.id)"
class="">
<span class="uk-label uk-label-primary uk-flex uk-flex-middle">
<span
class="uk-margin-small-right uk-width-expand uk-text-truncate">
<ng-container *ngIf="filter.type && (filter.type == 'boolean' || filter.type == 'triplet') else noboolean">
<span>{{filter.title}}:
{{(value.name=='true'||value.name=='Yes')?'Yes':'No'}}
</span>
</ng-container>
<ng-template #noboolean>
{{value.name}}
</ng-template></span>
<button [class.uk-disabled]="disabled" (click)="removeFilter(value, filter)" class="uk-close uk-icon" [disabled]="disabled">
<icon name="close" flex="true" ratio="0.7"></icon>
</button>
</span>
</li>
</ng-container>
</ng-container>
</ng-container>
</ul>
</div>
<a class="uk-position-center-left uk-blur-background" uk-slider-item="previous"><span uk-icon="chevron-left"></span></a>
<a class="uk-position-center-right uk-blur-background" uk-slider-item="next"><span uk-icon="chevron-right"></span></a>
</div>
</div> </div>
</h1> </h1>
</ng-template> </ng-template>
@ -170,10 +172,6 @@
<ng-container *ngFor="let filter of filters "> <ng-container *ngFor="let filter of filters ">
<li *ngIf="filter.values && filter.values.length > 0 <li *ngIf="filter.values && filter.values.length > 0
&& filter.filterId != 'resultbestaccessright' && filter.filterId != 'instancetypename' && filter.filterId != 'projectoamandatepublications'"> && filter.filterId != 'resultbestaccessright' && filter.filterId != 'instancetypename' && filter.filterId != 'projectoamandatepublications'">
<!-- <search-filter [filterValuesNum]="filterValuesNum" [showMoreInline]="showMoreFilterValuesInline"-->
<!-- [isDisabled]="disabled"-->
<!-- [filter]="filter" [showResultCount]=showResultCount-->
<!-- (onFilterChange)="filterChanged($event)" [actionRoute]="true"></search-filter>-->
<ng-container *ngTemplateOutlet="search_filter; context: {filter: filter, showResultCount: showResultCount}"></ng-container> <ng-container *ngTemplateOutlet="search_filter; context: {filter: filter, showResultCount: showResultCount}"></ng-container>
</li> </li>
</ng-container> </ng-container>
@ -190,31 +188,7 @@
</ul> </ul>
</div> </div>
</ng-template> </ng-template>
<ng-template #sorting let-mobile="mobile">
<div *ngIf="searchUtils.totalResults > 10 || sort || searchUtils.totalResults > searchUtils.size ||
(!loadPaging && oldTotalResults > searchUtils.size && searchUtils.status == errorCodes.LOADING)"
class="uk-grid uk-flex-middle uk-child-width-1-1 uk-child-width-1-2@m" uk-grid>
<div>
<div class="uk-grid uk-flex-middle uk-grid-column-collapse" uk-grid>
<div *ngIf="searchUtils.totalResults > 10 && !mobile" class="uk-width-small uk-margin-right">
<div input type="select" placeholder="Results per page" inputClass="flat x-small"
[options]="pageOptions" [(value)]="searchUtils.size" [disabled]="disabled"
(valueChange)="sizeChanged($event)"></div>
</div>
<search-sorting *ngIf="sort && searchUtils.totalResults > 0"
[entityType]="entityType" [sortBy]="searchUtils.sortBy"
(sortByChange)="sortByChanged($event)"
[isDisabled]="disabled">
</search-sorting>
</div>
</div>
<search-paging *ngIf="!mobile" [type]="type" [loadPaging]="loadPaging" [oldTotalResults]="oldTotalResults"
[searchUtils]="searchUtils" [results]="results" [baseUrl]="searchUtils.baseUrl"
[parameterNames]="parameterNames" [parameterValues]="parameterValues"
[isDisabled]="disabled">
</search-paging>
</div>
</ng-template>
<ng-template #main let-mobile="mobile"> <ng-template #main let-mobile="mobile">
<div *ngIf="mobile && showRefine && (searchUtils.refineStatus != errorCodes.LOADING || existingFiltersWithValues !== 0)" <div *ngIf="mobile && showRefine && (searchUtils.refineStatus != errorCodes.LOADING || existingFiltersWithValues !== 0)"
class="filters-toggle-button"> class="filters-toggle-button">
@ -228,7 +202,8 @@
</div> </div>
<!-- TODO - Clean up --> <!-- TODO - Clean up -->
<div *ngIf="!includeOnlyResultsAndFilter" [class]="usedBy != 'deposit' && usedBy != 'orcid' && (!customFilters || customFilters[0].queryFieldName != 'communityId') ? <div *ngIf="!includeOnlyResultsAndFilter" [class]="usedBy != 'deposit' && usedBy != 'orcid' &&
(!customFilters || (customFilters && customFilters[0].queryFieldName != 'communityId')) ?
(stickyForm?'':' ') : (stickyForm?'':' ') :
(+ (stickyForm?'':' uk-section') +' uk-padding-remove-bottom uk-padding-remove-top ' + (+ (stickyForm?'':' uk-section') +' uk-padding-remove-bottom uk-padding-remove-top ' +
((usedBy == 'deposit' || usedBy == 'orcid') ? ' uk-padding-remove-top ' : ' '))" ((usedBy == 'deposit' || usedBy == 'orcid') ? ' uk-padding-remove-top ' : ' '))"
@ -260,7 +235,7 @@
[advancedSearchLinkParameters]="this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)" [advancedSearchLinkParameters]="this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues)"
[simpleView]="simpleView" [formPlaceholderText]="formPlaceholderText" [isMobile]="mobile" [simpleView]="simpleView" [formPlaceholderText]="formPlaceholderText" [isMobile]="mobile"
[resultTypes]="resultTypes" [quickFilter]="quickFilter" [entitiesSelection]="entitiesSelection" [resultTypes]="resultTypes" [quickFilter]="quickFilter" [entitiesSelection]="entitiesSelection"
[showSwitchSearchLink]="showSwitchSearchLink" [customFilter]="customFilters[0]" [showSwitchSearchLink]="showSwitchSearchLink" [customFilter]="customFilters?customFilters[0]:null"
> >
</advanced-search-form> </advanced-search-form>
</div> </div>
@ -293,9 +268,6 @@
<icon name="close" ratio="1.5" visuallyHidden="close filters"></icon> <icon name="close" ratio="1.5" visuallyHidden="close filters"></icon>
</a> </a>
<div *ngIf="showOffCanvas" class="uk-padding-small uk-padding-remove-vertical"> <div *ngIf="showOffCanvas" class="uk-padding-small uk-padding-remove-vertical">
<div class="uk-margin-medium-top">
<ng-container *ngTemplateOutlet="sorting; context: {mobile: mobile}"></ng-container>
</div>
<div class="uk-margin-medium-top"> <div class="uk-margin-medium-top">
<ng-container *ngTemplateOutlet="filters_column; context: {}"></ng-container> <ng-container *ngTemplateOutlet="filters_column; context: {}"></ng-container>
</div> </div>
@ -314,9 +286,17 @@
</div> </div>
</div> </div>
</div> </div>
<div class="uk-container" [class.uk-container-large]="!mobile" [class.uk-container-expand]="mobile" [class.uk-padding-remove-horizontal]="mobile"> <div class="uk-container uk-margin-top" [class.uk-container-large]="!mobile" [class.uk-container-expand]="mobile" [class.uk-padding-remove-horizontal]="mobile">
<div class="uk-grid uk-margin-large-bottom" [class.uk-margin-top]="!mobile" uk-grid> <div class="uk-grid uk-margin-large-bottom" [class.uk-margin-top]="!mobile" uk-grid>
<div *ngIf="!mobile && showRefine && (results.length > 0 || (searchUtils.refineStatus == errorCodes.LOADING && searchUtils.status != errorCodes.LOADING) || (!hideFilters && <!-- <div *ngIf="!mobile && showRefine -->
<!-- && (searchUtils.refineStatus == errorCodes.DONE && ((orderedFilters && orderedFilters.length > 0) || (staticFilters && staticFilters.length > 0)-->
<!-- || (rangeFilters && rangeFilters.length > 0) || (filters && filters.length > 0)))-->
<!-- && (results.length > 0 || (searchUtils.refineStatus == errorCodes.LOADING && searchUtils.status != errorCodes.LOADING) || (!hideFilters &&-->
<!-- (existingFiltersWithValues > 0 || (selectedRangeFilters + selectedFilters + selectedTypesNum) > 0))) "-->
<!-- class="uk-width-1-4@m search-filters">-->
<!-- </div>-->
<div *ngIf="!mobile && showRefine
&& (results.length > 0 || (searchUtils.refineStatus == errorCodes.LOADING && searchUtils.status != errorCodes.LOADING) || (!hideFilters &&
(existingFiltersWithValues > 0 || (selectedRangeFilters + selectedFilters + selectedTypesNum) > 0))) " (existingFiltersWithValues > 0 || (selectedRangeFilters + selectedFilters + selectedTypesNum) > 0))) "
class="uk-width-1-4@m search-filters"> class="uk-width-1-4@m search-filters">
<ng-container *ngTemplateOutlet="filters_column; context: {}"></ng-container> <ng-container *ngTemplateOutlet="filters_column; context: {}"></ng-container>
@ -336,10 +316,10 @@
[href]="openaireLink+this.routerHelper.createQueryParamsString(this.parameterNames, this.parameterValues)" [href]="openaireLink+this.routerHelper.createQueryParamsString(this.parameterNames, this.parameterValues)"
target="_blank"> OpenAIRE - Explore</a>. target="_blank"> OpenAIRE - Explore</a>.
</div> </div>
<div class="uk-flex uk-flex-middle uk-flex-wrap uk-child-width-1-1 uk-child-width-auto@m" [class.uk-flex-between]="!mobile"
[class.uk-margin-top]="mobile"> <div class="uk-flex uk-flex-middle uk-child-width-auto uk-flex-between">
<!-- Total results, number of pages --> <!-- Total results, number of pages -->
<div class="uk-width-expand@m uk-margin-remove-bottom uk-text-truncate" [class.uk-margin-medium-right]="!mobile" [class.uk-h6]="!mobile" [class.uk-text-center]="mobile"> <div class="uk-margin-remove-bottom uk-text-truncate" [class.uk-margin-medium-right]="!mobile" [class.uk-margin-right]="mobile" [class.uk-h6]="!mobile">
<ng-container *ngIf="results && searchUtils.totalResults > 0"> <ng-container *ngIf="results && searchUtils.totalResults > 0">
<span>{{searchUtils.totalResults|number}}</span> <span>{{searchUtils.totalResults|number}}</span>
<span class="uk-text-meta uk-text-capitalize"> {{type}}</span> <span class="uk-text-meta uk-text-capitalize"> {{type}}</span>
@ -359,25 +339,56 @@
</ng-container> </ng-container>
</div> </div>
<!-- Download results --> <!-- Download results -->
<div *ngIf="showDownload && (searchUtils.status !== errorCodes.LOADING || !loadPaging)" <div *ngIf="mobile && showDownload && (searchUtils.status !== errorCodes.LOADING || !loadPaging)"
class="uk-margin-small-bottom uk-flex uk-margin-small-top" [class.uk-flex-center]="mobile" [class.uk-margin-medium-top]="mobile"> class="uk-flex uk-flex-center">
<search-download <search-download
*ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'" *ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'"
[isDisabled]="disabled" [isDisabled]="disabled"
[type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults"> [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults">
</search-download> </search-download>
<ng-container *ngIf="properties.zenodoDumpUrl && entityType == 'result'"> <ng-container *ngIf="properties.zenodoDumpUrl && entityType == 'result'">
<a [href]="properties.zenodoDumpUrl" target="_blank" class=" uk-margin-left uk-button uk-button-link uk-flex uk-flex-middle"> <a [href]="properties.zenodoDumpUrl" target="_blank" class=" uk-margin-left uk-button uk-button-link uk-flex uk-flex-middle">
<img src="assets/common-assets/common/zenodoDump.png" width="20"><span class="uk-margin-xsmall-left">Data dump</span> <img src="assets/common-assets/common/zenodoDump.png" alt="Zenodo dump" width="20"><span class="uk-margin-xsmall-left">Data dump</span>
</a> </a>
</ng-container> </ng-container>
</div> </div>
<div *ngIf="!mobile" class="uk-flex uk-flex-middle">
<div *ngIf="searchUtils.totalResults > 10 || sort || searchUtils.totalResults > searchUtils.size ||
(!loadPaging && oldTotalResults > searchUtils.size && searchUtils.status == errorCodes.LOADING)"
class="uk-grid uk-flex-middle uk-child-width-1-1 uk-child-width-1-2@m" uk-grid>
<div>
<div class="uk-grid uk-flex-middle uk-grid-column-collapse" uk-grid>
<search-sorting *ngIf="sort && searchUtils.totalResults > 0"
[entityType]="entityType" [sortBy]="searchUtils.sortBy"
(sortByChange)="sortByChanged($event)"
[isDisabled]="disabled">
</search-sorting>
</div>
</div>
</div>
<!-- Download results -->
<div *ngIf="showDownload && (searchUtils.status !== errorCodes.LOADING || !loadPaging)"
class="uk-margin-small-left uk-flex uk-flex-middle" [class.uk-flex-center]="mobile" [class.uk-margin-medium-top]="mobile">
<search-download
*ngIf="( entityType !='community' && entityType != 'stakeholder') && usedBy == 'search'"
[isDisabled]="disabled"
[type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults">
</search-download>
<ng-container *ngIf="properties.zenodoDumpUrl && entityType == 'result'">
<a [href]="properties.zenodoDumpUrl" target="_blank" class=" uk-margin-left uk-button uk-button-link uk-flex uk-flex-middle">
<img src="assets/common-assets/common/zenodoDump.png" alt="Zenodo dump" width="20"><span class="uk-margin-xsmall-left">Data dump</span>
</a>
</ng-container>
</div>
</div>
</div> </div>
<div *ngIf="(searchUtils.status !== errorCodes.LOADING || !loadPaging) && !mobile" class="uk-margin-top">
<ng-container *ngTemplateOutlet="selected_filters_pills;"></ng-container> <div *ngIf="(searchUtils.status !== errorCodes.LOADING || !loadPaging) && !mobile" class="uk-flex uk-flex-top">
</div> <!-- filters pills -->
<div *ngIf="!mobile" class="uk-margin-medium-topuk-margin-medium-top"> <div class="uk-width-expand@m">
<ng-container *ngTemplateOutlet="sorting; context: {mobile: mobile}"></ng-container> <ng-container *ngTemplateOutlet="selected_filters_pills;"></ng-container>
</div>
</div> </div>
<div [class]="searchUtils.page > pagingLimit ? 'search-results' : ''" <div [class]="searchUtils.page > pagingLimit ? 'search-results' : ''"
*ngIf="(searchUtils.page >= pagingLimit) && (searchUtils.totalResults > searchUtils.size*pagingLimit)"> *ngIf="(searchUtils.page >= pagingLimit) && (searchUtils.totalResults > searchUtils.size*pagingLimit)">

View File

@ -73,7 +73,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
@Input() @Input()
set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) { set customFilter(customFilter: SearchCustomFilter | SearchCustomFilter[]) {
if(!Array.isArray(customFilter)) { if(!Array.isArray(customFilter)) {
this.customFilters = [customFilter]; this.customFilters = customFilter?[customFilter]:null;
}else{ }else{
this.customFilters = customFilter; this.customFilters = customFilter;
} }
@ -131,6 +131,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
public parameterNames: string[] = []; public parameterNames: string[] = [];
public parameterValues: string[] = []; public parameterValues: string[] = [];
filterPillCharactersLimit: number = 35;
public csvLimit: number = 0; public csvLimit: number = 0;
public pagingLimit: number = 0; public pagingLimit: number = 0;
public resultsPerPage: number = 0; public resultsPerPage: number = 0;
@ -234,14 +235,14 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
} }
private getPageContents() { 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; this.pageContents = contents;
})); }));
} }
private getDivContents() { 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; this.divContents = contents;
})); }));
} }
@ -1084,7 +1085,7 @@ export class NewSearchPageComponent implements OnInit, OnDestroy, OnChanges {
let params = ""; let params = "";
let doisParams = ""; let doisParams = "";
var DOIs: Identifier[] = Identifier.getIdentifiersFromString(value); 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) { for (let identifier of DOIs) {
// console.log(identifier) // console.log(identifier)
// pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\" // pidclassid exact \"doi\" and pid exact \"10.1016/j.nima.2015.11.134\"

Some files were not shown because too many files have changed in this diff Show More