[angular-16-irish-monitor | WIP]: Add base components for stakeholder, indicators and sidebar. Deprecated StakeholderEntities.

This commit is contained in:
Konstantinos Triantafyllou 2023-11-13 15:00:05 +02:00
parent 1ff833ed8a
commit e80f73f9a9
23 changed files with 521 additions and 461 deletions

View File

@ -6,6 +6,9 @@ import {CommunityInfo} from "./community/communityInfo";
export class ConnectHelper { export class ConnectHelper {
public static getCommunityFromDomain(domain: string): string{ public static getCommunityFromDomain(domain: string): string{
if(properties.adminToolsPortalType === 'irish') {
return properties.adminToolsCommunity;
}
if(properties.environment == "development" && if(properties.environment == "development" &&
(properties.adminToolsPortalType == "connect" || properties.adminToolsPortalType == "community" (properties.adminToolsPortalType == "connect" || properties.adminToolsPortalType == "community"
|| properties.adminToolsPortalType == "aggregator" || properties.adminToolsPortalType == "eosc")) { || properties.adminToolsPortalType == "aggregator" || properties.adminToolsPortalType == "eosc")) {

View File

@ -1,17 +1,17 @@
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
import {StakeholderEntities} from "../../monitor/entities/stakeholder"; import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";
export class PortalUtils{ export class PortalUtils {
portalTypes: Option[] = [ portalTypes: Option[] = [
{value: 'explore', label: 'Explore Portal'}, {value: 'explore', label: 'Explore Portal'},
{value: 'connect', label: 'Connect portal'}, {value: 'connect', label: 'Connect portal'},
{value: 'monitor', label: 'Monitor portal'}, {value: 'monitor', label: 'Monitor portal'},
{value: 'community', label: 'Community Gateway'}, {value: 'community', label: 'Community Gateway'},
{value: 'funder', label: StakeholderEntities.FUNDER + ' Dashboard'}, {value: 'funder', label: StakeholderConfiguration.ENTITIES.funder + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'ri', label: StakeholderEntities.RI + ' Dashboard'}, {value: 'ri', label: StakeholderConfiguration.ENTITIES.ri + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'organization', label: StakeholderEntities.ORGANIZATION + ' Dashboard'}, {value: 'organization', label: StakeholderConfiguration.ENTITIES.organization + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
{value: 'project', label: StakeholderEntities.PROJECT + ' Dashboard'} {value: 'project', label: StakeholderConfiguration.ENTITIES.project + ' ' + StakeholderConfiguration.ENTITIES.stakeholder},
]; ];
} }

View File

@ -0,0 +1,42 @@
import {ChangeDetectorRef, Directive, OnInit} from "@angular/core";
import {BaseComponent} from "../../../sharedComponents/base/base.component";
import {MenuItem} from "../../../sharedComponents/menu";
import {LayoutService} from "./layout.service";
@Directive()
export class SidebarBaseComponent extends BaseComponent implements OnInit {
hasSidebar: boolean = false;
hasInternalSidebar: boolean = false;
/**
* Menu Items
* */
sideBarItems: MenuItem[] = [];
backItem: MenuItem = null;
protected layoutService: LayoutService;
protected cdr: ChangeDetectorRef;
constructor() {
super();
}
ngOnInit() {
this.subscriptions.push(this.layoutService.hasSidebar.subscribe(hasSidebar => {
this.hasSidebar = hasSidebar;
this.cdr.detectChanges();
}));
this.subscriptions.push(this.layoutService.hasInternalSidebar.subscribe(hasInternalSidebar => {
this.hasInternalSidebar = hasInternalSidebar;
this.cdr.detectChanges();
}));
this.layoutService.setOpen(true);
}
public get open() {
return this.layoutService.open;
}
public get hover() {
return this.layoutService.hover;
}
}

View File

@ -1,4 +1,5 @@
import {stakeholderTypes} from "../../monitor/entities/stakeholder"; import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";
export class User { export class User {
email: string; email: string;
@ -100,7 +101,7 @@ export class Session {
} }
public static isMonitorCurator(user: User): boolean { public static isMonitorCurator(user: User): boolean {
return stakeholderTypes.filter(stakeholderType => this.isTypeCurator(stakeholderType.value, user)).length > 0; return StakeholderConfiguration.TYPES.filter(stakeholderType => this.isTypeCurator(stakeholderType.value, user)).length > 0;
} }
public static isCommunityCurator(user: User): boolean { public static isCommunityCurator(user: User): boolean {
@ -112,7 +113,7 @@ export class Session {
} }
public static isCurator(type: string, user: User): boolean { public static isCurator(type: string, user: User): boolean {
return (type === 'community' || stakeholderTypes.find(stakeholderType => stakeholderType.value == type)) && this.isTypeCurator(type, user); return (type === 'community' || StakeholderConfiguration.TYPES.find(stakeholderType => stakeholderType.value == type)) && this.isTypeCurator(type, user);
} }
public static isPortalAdministrator(user: User): boolean { public static isPortalAdministrator(user: User): boolean {

View File

@ -1,11 +1,8 @@
import {Component, Input, OnDestroy, ViewChild} from "@angular/core"; import {Component, Input, ViewChild} from "@angular/core";
import {Stakeholder} from "../../../monitor/entities/stakeholder"; import {Stakeholder} from "../../../monitor/entities/stakeholder";
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
import {StakeholderUtils} from "../../utils/indicator-utils";
import {Option} from "../../../sharedComponents/input/input.component"; import {Option} from "../../../sharedComponents/input/input.component";
import {Subscription} from "rxjs"; import {Subscription} from "rxjs";
import {EnvProperties} from "../../../utils/properties/env-properties";
import {properties} from "src/environments/environment";
import {StakeholderService} from "../../../monitor/services/stakeholder.service"; import {StakeholderService} from "../../../monitor/services/stakeholder.service";
import {UtilitiesService} from "../../../services/utilities.service"; import {UtilitiesService} from "../../../services/utilities.service";
import {Role, Session, User} from "../../../login/utils/helper.class"; import {Role, Session, User} from "../../../login/utils/helper.class";
@ -16,121 +13,132 @@ import {NotificationUtils} from "../../../notifications/notification-utils";
import {Notification} from "../../../notifications/notifications"; import {Notification} from "../../../notifications/notifications";
import {NotificationHandler} from "../../../utils/notification-handler"; import {NotificationHandler} from "../../../utils/notification-handler";
import {StatsProfilesService} from "../../utils/services/stats-profiles.service"; import {StatsProfilesService} from "../../utils/services/stats-profiles.service";
import {StakeholderBaseComponent} from "../../utils/stakeholder-base.component";
@Component({ @Component({
selector: 'edit-stakeholder', selector: 'edit-stakeholder',
template: ` template: `
<form *ngIf="stakeholderFb" [formGroup]="stakeholderFb"> <div class="uk-margin-medium-bottom">
<div class="uk-grid uk-grid-large" uk-grid> <form *ngIf="stakeholderFb" [formGroup]="stakeholderFb">
<div class="uk-width-1-2@m"> <div class="uk-grid uk-grid-large" uk-grid>
<div input id="name" [formInput]="stakeholderFb.get('name')" <div class="uk-width-1-2@m">
placeholder="Name"></div> <div input id="name" [formInput]="stakeholderFb.get('name')"
</div> placeholder="Name"></div>
<div class="uk-width-1-2@m"> </div>
<div input [formInput]="stakeholderFb.get('alias')" <div class="uk-width-1-2@m">
placeholder="URL Alias"></div> <div input [formInput]="stakeholderFb.get('alias')"
</div> placeholder="URL Alias"></div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_id')"
placeholder="Index ID"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_name')"
placeholder="Index Name"></div>
</div>
<div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('index_shortName')"
placeholder="Index Short Name"></div>
</div>
<ng-container *ngIf="isCurator">
<div class="uk-width-1-3@m">
<div *ngIf="statsProfiles" input [formInput]="stakeholderFb.get('statsProfile')" [type]="'select'"
[options]="statsProfiles"
placeholder="Stats Profile"></div>
</div> </div>
<div class="uk-width-1-3@m"> <div class="uk-width-1-3@m">
<div input [formInput]="stakeholderFb.get('projectUpdateDate')" [type]="'date'" <div input [formInput]="stakeholderFb.get('index_id')"
placeholder="Last Project Update"></div> placeholder="Index ID"></div>
</div> </div>
</ng-container> <div class="uk-width-1-3@m">
<div class="uk-width-1-3@m"> <div input [formInput]="stakeholderFb.get('index_name')"
<div input [formInput]="stakeholderFb.get('locale')" [type]="'select'" placeholder="Index Name"></div>
[options]="stakeholderUtils.locales" </div>
placeholder="Locale"></div> <div class="uk-width-1-3@m">
</div> <div input [formInput]="stakeholderFb.get('index_shortName')"
<div class="uk-width-1-1"> placeholder="Index Short Name"></div>
<div input [type]="'textarea'" placeholder="Description" </div>
[rows]="4" [formInput]="stakeholderFb.get('description')"></div> <ng-container *ngIf="isCurator">
</div> <div class="uk-width-1-3@m">
<div class="uk-width-1-1"> <div *ngIf="statsProfiles" input [formInput]="stakeholderFb.get('statsProfile')"
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/> [type]="'select'"
<div *ngIf="!stakeholderFb.get('isUpload').value" class="uk-grid uk-grid-column-large" uk-grid> [options]="statsProfiles"
<div class="uk-margin-top uk-width-auto@l uk-width-1-1"> placeholder="Stats Profile"></div>
<div class="uk-grid uk-grid-column-large uk-flex-middle" uk-grid> </div>
<div class="uk-width-auto@l uk-width-1-1 uk-flex uk-flex-center"> <div class="uk-width-1-3@m">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle uk-flex-wrap" <div input [formInput]="stakeholderFb.get('projectUpdateDate')" [type]="'date'"
(click)="file.click()"> placeholder="Last Project Update"></div>
<icon name="cloud_upload" [flex]="true"></icon> </div>
<span class="uk-margin-small-left">Upload a file</span> </ng-container>
</button> <div class="uk-width-1-3@m">
</div> <div input [formInput]="stakeholderFb.get('locale')" [type]="'select'"
<div class="uk-text-center uk-text-bold uk-width-expand"> [options]="stakeholderUtils.locales"
OR placeholder="Locale"></div>
</div>
<div class="uk-width-1-1">
<div input [type]="'textarea'" placeholder="Description"
[rows]="4" [formInput]="stakeholderFb.get('description')"></div>
</div>
<div class="uk-width-1-1">
<input #file id="photo" type="file" class="uk-hidden" (change)="fileChangeEvent($event)"/>
<div *ngIf="!stakeholderFb.get('isUpload').value" class="uk-grid uk-grid-column-large" uk-grid>
<div class="uk-margin-xsmall-top uk-width-auto@l uk-width-1-1">
<div class="uk-grid uk-grid-column-large uk-flex-middle" uk-grid>
<div class="uk-width-auto@l uk-width-1-1 uk-flex uk-flex-center">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle uk-flex-wrap"
(click)="file.click()">
<icon name="cloud_upload" [flex]="true"></icon>
<span class="uk-margin-small-left">Upload a file</span>
</button>
</div>
<div class="uk-text-center uk-text-bold uk-width-expand">
OR
</div>
</div> </div>
</div> </div>
<div input class="uk-width-expand" type="logoURL" [placeholder]="'Link to the logo'"
[formInput]="stakeholderFb.get('logoUrl')"></div>
</div> </div>
<div input class="uk-width-expand" type="logoURL" [placeholder]="'Link to the logo'" <div *ngIf="stakeholderFb.get('isUpload').value" class="uk-width-1-1 uk-flex uk-flex-middle">
[formInput]="stakeholderFb.get('logoUrl')"></div> <div class="uk-card uk-card-default uk-text-center uk-border-circle">
<img class="uk-position-center uk-blend-multiply" [src]="photo">
</div>
<div class="uk-margin-left">
<button (click)="remove()" class="uk-button-danger uk-icon-button uk-icon-button-small">
<icon [flex]="true" ratio="0.8" name="delete"></icon>
</button>
</div>
<div class="uk-margin-small-left">
<button class="uk-button-secondary uk-icon-button uk-icon-button-small"
(click)="file.click()">
<icon [flex]="true" ratio="0.8" name="edit"></icon>
</button>
</div>
</div>
<!-- Full width error message -->
<div *ngIf="uploadError"
class="uk-text-danger uk-margin-small-top uk-width-1-1">{{uploadError}}</div>
</div> </div>
<div *ngIf="stakeholderFb.get('isUpload').value" class="uk-width-1-1 uk-flex uk-flex-middle"> <div class="uk-width-1-1">
<div class="uk-card uk-card-default uk-text-center uk-border-circle"> <div class="uk-grid uk-child-width-expand@m uk-child-width-1-1" uk-grid>
<img class="uk-position-center uk-blend-multiply" [src]="photo"> <div *ngIf="showVisibility">
</div> <div input [formInput]="stakeholderFb.get('visibility')"
<div class="uk-margin-left"> [placeholder]="'Select a status'"
<button (click)="remove()" class="uk-button-danger uk-icon-button uk-icon-button-small"> [options]="stakeholderUtils.visibilities" type="select"></div>
<icon [flex]="true" ratio="0.8" name="delete"></icon> </div>
</button> <div [class.uk-width-1-2@m]="!showVisibility && !showFunderType && !canChooseTemplate">
</div> <div input [formInput]="stakeholderFb.get('type')"
<div class="uk-margin-small-left"> [placeholder]="'Select a type of ' + entities.stakeholder"
<button class="uk-button-secondary uk-icon-button uk-icon-button-small" [options]="typesByRole" type="select"></div>
(click)="file.click()"> </div>
<icon [flex]="true" ratio="0.8" name="edit"></icon> <div *ngIf="showFunderType">
</button> <div input [formInput]="stakeholderFb.get('funderType')"
[placeholder]="'Select a type of ' + entities.funder"
[options]="stakeholderUtils.funderTypes" type="select"></div>
</div>
<div *ngIf="canChooseTemplate">
<div [placeholder]="'Select a template'"
input [formInput]="stakeholderFb.get('defaultId')"
[options]="defaultStakeholdersOptions" type="select"></div>
</div>
</div> </div>
</div> </div>
<!-- Full width error message -->
<div *ngIf="uploadError" class="uk-text-danger uk-margin-small-top uk-width-1-1">{{uploadError}}</div>
</div> </div>
<div [class]="canChooseTemplate ? 'uk-width-1-3@m' : 'uk-width-1-2@m'"> </form>
<div input [formInput]="stakeholderFb.get('visibility')" <div #notify [class.uk-hidden]="!stakeholderFb" notify-form
[placeholder]="'Select a status'" class="uk-width-1-1 uk-margin-large-top"></div>
[options]="stakeholderUtils.statuses" type="select"></div> </div>
</div>
<div [class]="canChooseTemplate ? 'uk-width-1-3@m' : 'uk-width-1-2@m'">
<div input [formInput]="stakeholderFb.get('type')"
[placeholder]="'Select a type'"
[options]="types" type="select"></div>
</div>
<ng-container *ngIf="canChooseTemplate">
<div class="uk-width-1-3@m">
<div [placeholder]="'Select a template'"
input [formInput]="stakeholderFb.get('defaultId')"
[options]="defaultStakeholdersOptions" type="select"></div>
</div>
</ng-container>
</div>
</form>
<div #notify [class.uk-hidden]="!stakeholderFb" notify-form
class="uk-width-1-1 uk-margin-large-top uk-margin-medium-bottom"></div>
`, `,
styleUrls: ['edit-stakeholder.component.less'] styleUrls: ['edit-stakeholder.component.less']
}) })
export class EditStakeholderComponent implements OnDestroy { export class EditStakeholderComponent extends StakeholderBaseComponent {
@Input() @Input()
public disableAlias: boolean = false; public disableAlias: boolean = false;
public stakeholderFb: UntypedFormGroup; public stakeholderFb: UntypedFormGroup;
public secure: boolean = false; public secure: boolean = false;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public defaultStakeholdersOptions: Option[]; public defaultStakeholdersOptions: Option[];
public defaultStakeholders: Stakeholder[]; public defaultStakeholders: Stakeholder[];
public alias: string[]; public alias: string[];
@ -138,10 +146,8 @@ export class EditStakeholderComponent implements OnDestroy {
public isDefault: boolean; public isDefault: boolean;
public isNew: boolean; public isNew: boolean;
public loading: boolean = false; public loading: boolean = false;
public types: Option[]; public typesByRole: Option[];
public statsProfiles: string[]; public statsProfiles: string[];
public properties: EnvProperties = properties;
private subscriptions: any[] = [];
/** /**
* Photo upload * Photo upload
* */ * */
@ -153,21 +159,26 @@ export class EditStakeholderComponent implements OnDestroy {
user: User; user: User;
@ViewChild('notify', {static: true}) notify: NotifyFormComponent; @ViewChild('notify', {static: true}) notify: NotifyFormComponent;
private notification: Notification; private notification: Notification;
constructor(private fb: UntypedFormBuilder, constructor(private fb: UntypedFormBuilder,
private stakeholderService: StakeholderService, private stakeholderService: StakeholderService,
private statsProfileService: StatsProfilesService, private statsProfileService: StatsProfilesService,
private utilsService: UtilitiesService, private userManagementService: UserManagementService,) { private utilsService: UtilitiesService, private userManagementService: UserManagementService,) {
super();
} }
ngOnDestroy() { ngOnDestroy() {
this.reset(); this.reset();
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) {
this.reset(); this.reset();
this.deleteCurrentPhoto = false; this.deleteCurrentPhoto = false;
this.stakeholder = stakeholder; this.stakeholder = stakeholder;
if (this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities)) {
this.stakeholder.visibility = this.stakeholderUtils.defaultValue(this.stakeholderUtils.visibilities);
}
this.alias = alias; this.alias = alias;
this.defaultStakeholders = defaultStakeholders; this.defaultStakeholders = defaultStakeholders;
this.isDefault = isDefault; this.isDefault = isDefault;
@ -183,7 +194,7 @@ export class EditStakeholderComponent implements OnDestroy {
} else { } else {
this.statsProfiles = []; this.statsProfiles = [];
} }
this.types = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias); this.typesByRole = this.stakeholderUtils.getTypesByUserRoles(this.user, this.stakeholder.alias);
this.stakeholderFb = this.fb.group({ this.stakeholderFb = this.fb.group({
_id: this.fb.control(this.stakeholder._id), _id: this.fb.control(this.stakeholder._id),
defaultId: this.fb.control(this.stakeholder.defaultId), defaultId: this.fb.control(this.stakeholder.defaultId),
@ -197,15 +208,16 @@ export class EditStakeholderComponent implements OnDestroy {
projectUpdateDate: this.fb.control(this.stakeholder.projectUpdateDate), projectUpdateDate: this.fb.control(this.stakeholder.projectUpdateDate),
creationDate: this.fb.control(this.stakeholder.creationDate), creationDate: this.fb.control(this.stakeholder.creationDate),
alias: this.fb.control(this.stakeholder.alias, alias: this.fb.control(this.stakeholder.alias,
[ [
Validators.required, Validators.required,
this.stakeholderUtils.aliasValidatorString( this.stakeholderUtils.aliasValidatorString(
this.alias.filter(alias => alias !== this.stakeholder.alias) this.alias.filter(alias => alias !== this.stakeholder.alias)
)] )]
), ),
isDefault: this.fb.control((this.isDefault)), isDefault: this.fb.control((this.isDefault)),
visibility: this.fb.control(this.stakeholder.visibility, Validators.required), visibility: this.fb.control(this.stakeholder.visibility, Validators.required),
type: this.fb.control(this.stakeholder.type, Validators.required), type: this.fb.control(this.stakeholder.type, Validators.required),
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),
logoUrl: this.fb.control(this.stakeholder.logoUrl), logoUrl: this.fb.control(this.stakeholder.logoUrl),
@ -234,7 +246,7 @@ export class EditStakeholderComponent implements OnDestroy {
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(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);
@ -269,29 +281,29 @@ export class EditStakeholderComponent implements OnDestroy {
} }
})); }));
} }
public get isAdmin() { public get isAdmin() {
return Session.isPortalAdministrator(this.user); return Session.isPortalAdministrator(this.user);
} }
public get isCurator() { public get isCurator() {
return this.stakeholder && (this.isAdmin || Session.isCurator(this.stakeholder.type, this.user)); return this.stakeholder && (this.isAdmin || Session.isCurator(this.stakeholder.type, this.user));
} }
public get disabled(): boolean { public get disabled(): boolean {
return (this.stakeholderFb && this.stakeholderFb.invalid) || return (this.stakeholderFb && this.stakeholderFb.invalid) ||
(this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) || (this.stakeholderFb && this.stakeholderFb.pristine && !this.isNew && !this.file) ||
(this.uploadError && this.uploadError.length > 0); (this.uploadError && this.uploadError.length > 0);
} }
public get dirty(): boolean { public get dirty(): boolean {
return this.stakeholderFb && this.stakeholderFb.dirty; return this.stakeholderFb && this.stakeholderFb.dirty;
} }
public get canChooseTemplate(): boolean { public get canChooseTemplate(): boolean {
return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions; return this.isNew && this.stakeholderFb.get('type').valid && !!this.defaultStakeholdersOptions;
} }
reset() { reset() {
this.uploadError = null; this.uploadError = null;
this.stakeholderFb = null; this.stakeholderFb = null;
@ -301,9 +313,9 @@ export class EditStakeholderComponent implements OnDestroy {
} }
}); });
} }
onTypeChange(value, defaultStakeholders: Stakeholder[]) { onTypeChange(value, defaultStakeholders: Stakeholder[]) {
this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew)?[]:Validators.required)); this.stakeholderFb.setControl('defaultId', this.fb.control(this.stakeholder.defaultId, (this.isDefault && !this.isNew) ? [] : Validators.required));
this.defaultStakeholdersOptions = [{ this.defaultStakeholdersOptions = [{
label: 'New blank profile', label: 'New blank profile',
value: '-1' value: '-1'
@ -315,7 +327,7 @@ export class EditStakeholderComponent implements OnDestroy {
}) })
}); });
} }
public save(callback: Function, errorCallback: Function = null) { public save(callback: Function, errorCallback: Function = null) {
this.loading = true; this.loading = true;
if (this.file) { if (this.file) {
@ -335,14 +347,14 @@ export class EditStakeholderComponent implements OnDestroy {
this.saveStakeholder(callback, errorCallback); this.saveStakeholder(callback, errorCallback);
} }
} }
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 defaultStakeholder = this.defaultStakeholders.find(value => value._id === this.stakeholderFb.getRawValue().defaultId);
this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(), this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.getRawValue(),
(defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault)); (defaultStakeholder ? defaultStakeholder.topics : []), this.stakeholderFb.getRawValue().isDefault));
this.removePhoto(); this.removePhoto();
if(this.stakeholderFb.getRawValue().isDefault) { if (this.stakeholderFb.getRawValue().isDefault) {
this.stakeholderFb.get('defaultId').setValue(null); this.stakeholderFb.get('defaultId').setValue(null);
} }
this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, this.subscriptions.push(this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL,
@ -381,7 +393,7 @@ export class EditStakeholderComponent implements OnDestroy {
})); }));
} }
} }
fileChangeEvent(event) { fileChangeEvent(event) {
if (event.target.files && event.target.files[0]) { if (event.target.files && event.target.files[0]) {
this.file = event.target.files[0]; this.file = event.target.files[0];
@ -407,13 +419,13 @@ export class EditStakeholderComponent implements OnDestroy {
} }
} }
} }
initPhoto() { initPhoto() {
if (this.stakeholderFb.getRawValue().isUpload) { if (this.stakeholderFb.getRawValue().isUpload) {
this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value; this.photo = this.properties.utilsService + "/download/" + this.stakeholderFb.get('logoUrl').value;
} }
} }
removePhoto() { removePhoto() {
if (this.file) { if (this.file) {
if (typeof document != 'undefined') { if (typeof document != 'undefined') {
@ -423,7 +435,7 @@ export class EditStakeholderComponent implements OnDestroy {
this.file = null; this.file = null;
} }
} }
remove() { remove() {
this.stakeholderFb.get('isUpload').setValue(false); this.stakeholderFb.get('isUpload').setValue(false);
this.stakeholderFb.get('isUpload').markAsDirty(); this.stakeholderFb.get('isUpload').markAsDirty();
@ -433,11 +445,15 @@ export class EditStakeholderComponent implements OnDestroy {
this.deleteCurrentPhoto = true; this.deleteCurrentPhoto = true;
} }
} }
public deletePhoto() { public deletePhoto() {
if (this.stakeholder.logoUrl && this.stakeholder.isUpload) { if (this.stakeholder.logoUrl && this.stakeholder.isUpload) {
this.subscriptions.push(this.utilsService.deletePhoto(this.properties.utilsService + '/delete/' + this.subscriptions.push(this.utilsService.deletePhoto(this.properties.utilsService + '/delete/' +
encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholder.alias) + "/" + this.stakeholder.logoUrl).subscribe()); encodeURIComponent(this.stakeholder.type) + "/" + encodeURIComponent(this.stakeholder.alias) + "/" + this.stakeholder.logoUrl).subscribe());
} }
} }
get showFunderType() {
return super.showFunderType && this.stakeholderFb?.get('type').value === 'funder' && !this.isDefault;
}
} }

View File

@ -1,29 +1,28 @@
import {ChangeDetectorRef, Component, OnDestroy, OnInit, ViewChild} from "@angular/core"; import {ChangeDetectorRef, Component, OnInit, ViewChild} from "@angular/core";
import {StakeholderService} from "../../monitor/services/stakeholder.service"; import {StakeholderService} from "../../monitor/services/stakeholder.service";
import {EnvProperties} from "../../utils/properties/env-properties";
import {Stakeholder} from "../../monitor/entities/stakeholder"; import {Stakeholder} from "../../monitor/entities/stakeholder";
import { Subscription, zip} from "rxjs"; import {zip} from "rxjs";
import {EditStakeholderComponent} from "./edit-stakeholder/edit-stakeholder.component"; import {EditStakeholderComponent} from "./edit-stakeholder/edit-stakeholder.component";
import {properties} from "src/environments/environment";
import {Title} from "@angular/platform-browser"; import {Title} from "@angular/platform-browser";
import {BaseComponent} from "../../sharedComponents/base/base.component";
import {ActivatedRoute} from "@angular/router";
@Component({ @Component({
selector: 'general', selector: 'general',
templateUrl: "./general.component.html" templateUrl: "./general.component.html"
}) })
export class GeneralComponent implements OnInit, OnDestroy { export class GeneralComponent extends BaseComponent implements OnInit {
public stakeholder: Stakeholder; public stakeholder: Stakeholder;
public alias: string[]; public alias: string[];
public properties: EnvProperties = properties;
public defaultStakeholders: Stakeholder[]; public defaultStakeholders: Stakeholder[];
public loading: boolean = false; public loading: boolean = false;
private subscriptions: any[] = [];
@ViewChild('editStakeholderComponent') editStakeholderComponent: EditStakeholderComponent; @ViewChild('editStakeholderComponent') editStakeholderComponent: EditStakeholderComponent;
constructor(private stakeholderService: StakeholderService, constructor(private stakeholderService: StakeholderService,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private title: Title) { protected _route: ActivatedRoute,
protected _title: Title) {
super();
} }
ngOnInit() { ngOnInit() {
@ -32,7 +31,8 @@ export class GeneralComponent implements OnInit, OnDestroy {
this.stakeholder = stakeholder; this.stakeholder = stakeholder;
this.cdr.detectChanges(); this.cdr.detectChanges();
if(this.stakeholder) { if(this.stakeholder) {
this.title.setTitle(this.stakeholder.name + " | General"); this.title = this.stakeholder.name + " | General";
this.setMetadata();
let data = zip( let data = zip(
this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL), this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL),
this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL) this.stakeholderService.getAlias(this.properties.monitorServiceAPIURL)
@ -51,10 +51,9 @@ export class GeneralComponent implements OnInit, OnDestroy {
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)
} }
public save() { public save() {
this.loading = true; this.loading = true;
this.editStakeholderComponent.save((stakeholder) => { this.editStakeholderComponent.save(stakeholder => {
this.stakeholder = stakeholder; this.stakeholder = stakeholder;
this.stakeholderService.setStakeholder(this.stakeholder); this.stakeholderService.setStakeholder(this.stakeholder);
this.reset(); this.reset();
@ -64,12 +63,4 @@ export class GeneralComponent implements OnInit, OnDestroy {
this.loading = false; this.loading = false;
}); });
} }
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if(subscription instanceof Subscription) {
subscription.unsubscribe();
}
});
}
} }

View File

@ -60,7 +60,7 @@
<div class="uk-card uk-card-default uk-card-body uk-position-relative" [ngClass]="stakeholder.type"> <div class="uk-card uk-card-default uk-card-body uk-position-relative" [ngClass]="stakeholder.type">
<div class="uk-position-top-right uk-margin-small-right uk-margin-small-top"> <div class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle"> <a class="uk-link-reset uk-flex uk-flex-middle">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)" ratio="0.6"></icon> <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(stakeholder.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0;"> <div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0;">
@ -71,8 +71,8 @@
<li *ngIf="isCurator"> <li *ngIf="isCurator">
<a (click)="createReport(stakeholder);hide(element)">Cache Indicators</a> <a (click)="createReport(stakeholder);hide(element)">Cache Indicators</a>
</li> </li>
<li class="uk-nav-divider"></li> <li *ngIf="showVisibility" class="uk-nav-divider"></li>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-template *ngIf="showVisibility" ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<li [class.uk-active]="stakeholder.visibility === v.value"> <li [class.uk-active]="stakeholder.visibility === v.value">
<a (click)="changeStakeholderStatus(stakeholder, v.value);hide(element)"> <a (click)="changeStakeholderStatus(stakeholder, v.value);hide(element)">
<div class="uk-flex uk-flex-middle"> <div class="uk-flex uk-flex-middle">

View File

@ -1,9 +1,7 @@
import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core"; import {Component, OnDestroy, OnInit, ViewChild} from "@angular/core";
import {StakeholderService} from "../../monitor/services/stakeholder.service"; import {StakeholderService} from "../../monitor/services/stakeholder.service";
import {EnvProperties} from "../../utils/properties/env-properties"; import {Stakeholder, Visibility} from "../../monitor/entities/stakeholder";
import {Stakeholder, StakeholderEntities, Visibility} from "../../monitor/entities/stakeholder"; import {zip} from "rxjs";
import {Subscriber, zip} from "rxjs";
import {StakeholderUtils} from "../utils/indicator-utils";
import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms"; import {UntypedFormBuilder, UntypedFormGroup} from "@angular/forms";
import {AlertModal} from "../../utils/modal/alert"; import {AlertModal} from "../../utils/modal/alert";
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
@ -11,11 +9,10 @@ import {Title} from "@angular/platform-browser";
import {UserManagementService} from "../../services/user-management.service"; import {UserManagementService} from "../../services/user-management.service";
import {Session} from "../../login/utils/helper.class"; import {Session} from "../../login/utils/helper.class";
import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component"; import {EditStakeholderComponent} from "../general/edit-stakeholder/edit-stakeholder.component";
import {properties} from "src/environments/environment";
import {ActivatedRoute} from "@angular/router"; import {ActivatedRoute} from "@angular/router";
import {CacheIndicatorsService} from "../utils/cache-indicators/cache-indicators.service"; import {CacheIndicatorsService} from "../utils/cache-indicators/cache-indicators.service";
import {NotificationHandler} from "../../utils/notification-handler"; import {NotificationHandler} from "../../utils/notification-handler";
import {BaseComponent} from "../../sharedComponents/base/base.component"; import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
type Tab = 'all' | 'templates'| 'profiles'; type Tab = 'all' | 'templates'| 'profiles';
@ -26,10 +23,9 @@ declare var UIkit;
templateUrl: "./manageStakeholders.component.html", templateUrl: "./manageStakeholders.component.html",
styleUrls: ["./manageStakeholders.component.less"] styleUrls: ["./manageStakeholders.component.less"]
}) })
export class ManageStakeholdersComponent extends BaseComponent implements OnInit, OnDestroy { export class ManageStakeholdersComponent extends StakeholderBaseComponent implements OnInit, OnDestroy {
public loading: boolean = true; public loading: boolean = true;
public deleteLoading: boolean = false; public deleteLoading: boolean = false;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public defaultStakeholders: Stakeholder[]; public defaultStakeholders: Stakeholder[];
public stakeholders: Stakeholder[]; public stakeholders: Stakeholder[];
public alias: string[]; public alias: string[];
@ -283,17 +279,4 @@ export class ManageStakeholdersComponent extends BaseComponent implements OnInit
return this.stakeholderUtils.types.slice(0, this.stakeholderUtils.types.length - 1).map(type => type.label).join(', ') + return this.stakeholderUtils.types.slice(0, this.stakeholderUtils.types.length - 1).map(type => type.label).join(', ') +
' or ' + this.stakeholderUtils.types[this.stakeholderUtils.types.length - 1].label ' or ' + this.stakeholderUtils.types[this.stakeholderUtils.types.length - 1].label
} }
private isTab(tab: Tab): boolean {
switch (tab) {
case "all":
return true;
case "profiles":
return true;
case "templates":
return true;
default:
return false;
}
}
} }

View File

@ -39,26 +39,28 @@
<div *ngIf="!dragging" <div *ngIf="!dragging"
class="uk-position-top-right uk-margin-small-right uk-margin-small-top"> class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing"> <a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon> <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0"> <div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator"> <ng-container *ngIf="isCurator">
<li><a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a></li> <li><a (click)="editNumberIndicatorOpen(number, indicator._id); hide(element)">Edit</a></li>
<li class="uk-nav-divider"></li>
</ng-container> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-container *ngIf="showVisibility">
<li> <li *ngIf="isCurator" class="uk-nav-divider"></li>
<a (click)="changeIndicatorStatus(number._id, indicator, v.value);hide(element)"> <ng-template ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<div class="uk-flex uk-flex-middle"> <li>
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon> <a (click)="changeIndicatorStatus(number._id, indicator, v.value);hide(element)">
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span> <div class="uk-flex uk-flex-middle">
<icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon> <icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
</div> <span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
</a> <icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
</li> </div>
</ng-template> </a>
</li>
</ng-template>
</ng-container>
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator"> <ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li class="uk-nav-divider"> <li class="uk-nav-divider">
<li><a (click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a></li> <li><a (click)="deleteIndicatorOpen(number, indicator._id, 'number', 'delete');hide(element)">Delete</a></li>
@ -136,26 +138,28 @@
<div *ngIf="!dragging" <div *ngIf="!dragging"
class="uk-position-top-right uk-margin-small-right uk-margin-small-top"> class="uk-position-top-right uk-margin-small-right uk-margin-small-top">
<a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing"> <a class="uk-link-reset uk-flex uk-flex-middle" [class.uk-disabled]="editing">
<icon [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon> <icon *ngIf="showVisibility" [flex]="true" [name]="stakeholderUtils.visibilityIcon.get(indicator.visibility)" ratio="0.6"></icon>
<icon [flex]="true" name="more_vert"></icon> <icon [flex]="true" name="more_vert"></icon>
</a> </a>
<div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0"> <div #element class="uk-dropdown" uk-dropdown="mode: click; pos: bottom-left; offset: 5; delay-hide: 0">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<ng-container *ngIf="isCurator"> <ng-container *ngIf="isCurator">
<li><a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a></li> <li><a (click)="editChartIndicatorOpen(chart, indicator._id); hide(element)">Edit</a></li>
<li class="uk-nav-divider"></li>
</ng-container> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-container *ngIf="showVisibility">
<li> <li *ngIf="isCurator" class="uk-nav-divider"></li>
<a (click)="changeIndicatorStatus(chart._id, indicator, v.value);"> <ng-template ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<div class="uk-flex uk-flex-middle"> <li>
<icon [flex]="true" [name]="v.icon" ratio="0.6"></icon> <a (click)="changeIndicatorStatus(chart._id, indicator, v.value);">
<span class="uk-margin-small-left uk-width-expand">{{v.label}}</span> <div class="uk-flex uk-flex-middle">
<icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon> <icon [flex]="true" [name]="v.icon" ratio="0.6"></icon>
</div> <span class="uk-margin-small-left uk-width-expand">{{v.label}}</span>
</a> <icon *ngIf="indicator.visibility === v.value" [flex]="true" name="done" class="uk-text-secondary" ratio="0.8"></icon>
</li> </div>
</ng-template> </a>
</li>
</ng-template>
</ng-container>
<ng-container *ngIf="!indicator.defaultId && !editing && isCurator"> <ng-container *ngIf="!indicator.defaultId && !editing && isCurator">
<li class="uk-nav-divider"> <li class="uk-nav-divider">
<li><a (click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a></li> <li><a (click)="deleteIndicatorOpen(chart, indicator._id, 'chart', 'delete');hide(element)">Delete</a></li>
@ -231,8 +235,8 @@
<div input class="uk-width-1-1" *ngIf="stakeholder.defaultId" [formInput]="numberIndicatorFb.get('additionalDescription')" <div input class="uk-width-1-1" *ngIf="stakeholder.defaultId" [formInput]="numberIndicatorFb.get('additionalDescription')"
placeholder="Description" type="textarea"> placeholder="Description" type="textarea">
</div> </div>
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('visibility')" <div *ngIf="showVisibility" input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('visibility')"
placeholder="Visibility" [options]="stakeholderUtils.visibility" type="select"> placeholder="Visibility" [options]="stakeholderUtils.visibilities" type="select">
</div> </div>
<div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('width')" <div input class="uk-width-1-2@m" [formInput]="numberIndicatorFb.get('width')"
placeholder="Number Size" [options]="indicatorUtils.indicatorSizes" type="select"> placeholder="Number Size" [options]="indicatorUtils.indicatorSizes" type="select">
@ -346,8 +350,8 @@
<div *ngIf="stakeholder.defaultId" input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('additionalDescription')" <div *ngIf="stakeholder.defaultId" input class="uk-width-1-1" [formInput]="chartIndicatorFb.get('additionalDescription')"
placeholder="Description" type="textarea"> placeholder="Description" type="textarea">
</div> </div>
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('visibility')" <div *ngIf="showVisibility" input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('visibility')"
placeholder="Status" [options]="stakeholderUtils.visibility" type="select"> placeholder="Status" [options]="stakeholderUtils.visibilities" type="select">
</div> </div>
<div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('width')" placeholder="Chart width" <div input class="uk-width-1-2@m" [formInput]="chartIndicatorFb.get('width')" placeholder="Chart width"
[options]="indicatorUtils.indicatorSizes" type="select"> [options]="indicatorUtils.indicatorSizes" type="select">

View File

@ -5,7 +5,6 @@ import {
HostListener, HostListener,
Input, Input,
OnChanges, OnChanges,
OnDestroy,
OnInit, OnInit,
SimpleChanges, SimpleChanges,
ViewChild ViewChild
@ -20,7 +19,6 @@ import {
Stakeholder, Stakeholder,
Visibility Visibility
} from "../../monitor/entities/stakeholder"; } from "../../monitor/entities/stakeholder";
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
import { import {
AbstractControl, AbstractControl,
UntypedFormArray, UntypedFormArray,
@ -34,7 +32,6 @@ import {StatisticsService} from "../utils/services/statistics.service";
import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser"; import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";
import {Reorder, StakeholderService} from "../../monitor/services/stakeholder.service"; import {Reorder, StakeholderService} from "../../monitor/services/stakeholder.service";
import {EnvProperties} from "../../utils/properties/env-properties";
import {Observable, Subscriber} from "rxjs"; import {Observable, Subscriber} from "rxjs";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service"; import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
import {Router} from "@angular/router"; import {Router} from "@angular/router";
@ -44,8 +41,8 @@ import {Notification} from "../../notifications/notifications";
import {NotificationUtils} from "../../notifications/notification-utils"; import {NotificationUtils} from "../../notifications/notification-utils";
import {NotifyFormComponent} from "../../notifications/notify-form/notify-form.component"; import {NotifyFormComponent} from "../../notifications/notify-form/notify-form.component";
import {NotificationService} from "../../notifications/notification.service"; import {NotificationService} from "../../notifications/notification.service";
import {properties} from "src/environments/environment";
import {NotificationHandler} from "../../utils/notification-handler"; import {NotificationHandler} from "../../utils/notification-handler";
import {IndicatorStakeholderBaseComponent} from "../utils/stakeholder-base.component";
declare var UIkit; declare var UIkit;
@ -54,10 +51,9 @@ declare var UIkit;
templateUrl: './indicators.component.html', templateUrl: './indicators.component.html',
styleUrls: ['indicators.component.less'] styleUrls: ['indicators.component.less']
}) })
export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit { export class IndicatorsComponent extends IndicatorStakeholderBaseComponent implements OnInit, OnChanges, AfterViewInit {
filesToUpload: Array<File>; filesToUpload: Array<File>;
errorMessage = ""; errorMessage = "";
public properties: EnvProperties = properties;
@Input() @Input()
public topicIndex: number = 0; public topicIndex: number = 0;
@Input() @Input()
@ -71,8 +67,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
@Input() @Input()
public user: User = null; public user: User = null;
public preview: string; public preview: string;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public numberIndicatorFb: UntypedFormGroup; public numberIndicatorFb: UntypedFormGroup;
public chartIndicatorFb: UntypedFormGroup; public chartIndicatorFb: UntypedFormGroup;
public chartSections: UntypedFormArray; public chartSections: UntypedFormArray;
@ -118,7 +112,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
/** /**
* Subscriptions * Subscriptions
**/ **/
private subscriptions: any[] = [];
private urlSubscriptions: any[] = []; private urlSubscriptions: any[] = [];
private numberSubscription: any[] = []; private numberSubscription: any[] = [];
@ -127,9 +120,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
private statisticsService: StatisticsService, private statisticsService: StatisticsService,
private notificationService: NotificationService, private notificationService: NotificationService,
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
private router: Router, protected _router: Router,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private sanitizer: DomSanitizer) { private sanitizer: DomSanitizer) {
super()
this.filesToUpload = []; this.filesToUpload = [];
} }
@ -146,13 +140,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.subscriptions.forEach(value => { super.ngOnDestroy();
if (value instanceof Subscriber) {
value.unsubscribe();
} else if (value instanceof Function) {
value();
}
});
this.urlSubscriptions.forEach(value => { this.urlSubscriptions.forEach(value => {
if (value instanceof Subscriber) { if (value instanceof Subscriber) {
value.unsubscribe(); value.unsubscribe();

View File

@ -26,12 +26,11 @@
<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"> <a class="uk-link-reset uk-flex uk-flex-middle">
<icon [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 <div #element 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">
<li> <li>
@ -59,9 +58,10 @@
</div> </div>
</a> </a>
</li> </li>
<li class="uk-nav-divider"></li>
</ng-container> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-container *ngIf="showVisibility">
<li *ngIf="isCurator" class="uk-nav-divider"></li>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<li [class.uk-active]="topic.visibility === v.value"> <li [class.uk-active]="topic.visibility === v.value">
<a (click)="openVisibilityModal(i, v.value, 'topic'); hide(element)"> <a (click)="openVisibilityModal(i, v.value, 'topic'); hide(element)">
<div class="uk-flex uk-flex-middle"> <div class="uk-flex uk-flex-middle">
@ -73,6 +73,7 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
</ng-container>
<ng-container *ngIf="!topic.defaultId && isCurator"> <ng-container *ngIf="!topic.defaultId && isCurator">
<li class="uk-nav-divider"> <li class="uk-nav-divider">
<li> <li>
@ -103,7 +104,7 @@
<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"> <a class="uk-link-reset uk-flex uk-flex-middle">
<icon [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>
@ -137,9 +138,11 @@
</div> </div>
</a> </a>
</li> </li>
<li class="uk-nav-divider"></li>
</ng-container> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-container *ngIf="showVisibility">
<li *ngIf="isCurator" class="uk-nav-divider"></li>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<li [class.uk-active]="category.visibility === v.value"> <li [class.uk-active]="category.visibility === v.value">
<a (click)="openVisibilityModal(j, v.value, 'category'); hide(element)"> <a (click)="openVisibilityModal(j, v.value, 'category'); hide(element)">
<div class="uk-flex uk-flex-middle"> <div class="uk-flex uk-flex-middle">
@ -151,6 +154,7 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
</ng-container>
<ng-container *ngIf="!category.defaultId && isCurator"> <ng-container *ngIf="!category.defaultId && isCurator">
<li class="uk-nav-divider"> <li class="uk-nav-divider">
<li> <li>
@ -191,8 +195,8 @@
</div> </div>
</aside> </aside>
<div #pageContent *ngIf="stakeholder && filters" class="uk-width-1-1" page-content> <div #pageContent *ngIf="stakeholder && filters" class="uk-width-1-1" page-content>
<div actions> <div actions class="uk-margin-medium-top">
<div *ngIf="stakeholder.topics.length > 0" class="uk-flex uk-flex-center uk-margin-medium-top uk-flex-right@m uk-width-1-1"> <div *ngIf="stakeholder.topics.length > 0 && showVisibility" class="uk-flex uk-flex-center uk-flex-right@m uk-width-1-1">
<button class="uk-button uk-button-primary uk-flex uk-flex-middle"> <button class="uk-button uk-button-primary uk-flex uk-flex-middle">
<icon name="visibility" [flex]="true"></icon> <icon name="visibility" [flex]="true"></icon>
<span class="uk-margin-small-left uk-margin-small-right">Preview</span> <span class="uk-margin-small-left uk-margin-small-right">Preview</span>
@ -229,7 +233,7 @@
[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"> <a class="uk-link-reset uk-flex uk-flex-middle">
<icon [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>
@ -279,9 +283,10 @@
</div> </div>
</a> </a>
</li> </li>
<li class="uk-nav-divider"></li>
</ng-container> </ng-container>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibility" let-v> <ng-container *ngIf="showVisibility">
<li *ngIf="isCurator" class="uk-nav-divider"></li>
<ng-template ngFor [ngForOf]="stakeholderUtils.visibilities" let-v>
<li [class.uk-active]="subCategory.visibility === v.value"> <li [class.uk-active]="subCategory.visibility === v.value">
<a (click)="openVisibilityModal(i, v.value, 'subcategory'); hide(element)"> <a (click)="openVisibilityModal(i, v.value, 'subcategory'); hide(element)">
<div class="uk-flex uk-flex-middle"> <div class="uk-flex uk-flex-middle">
@ -293,6 +298,7 @@
</a> </a>
</li> </li>
</ng-template> </ng-template>
</ng-container>
<ng-container *ngIf="!subCategory.defaultId && isCurator"> <ng-container *ngIf="!subCategory.defaultId && isCurator">
<li class="uk-nav-divider"> <li class="uk-nav-divider">
<li> <li>
@ -348,8 +354,8 @@
<div *ngIf="form" [class.uk-hidden]="loading" <div *ngIf="form" [class.uk-hidden]="loading"
class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="form" uk-grid> class="uk-grid uk-padding uk-padding-remove-horizontal uk-child-width-1-1" [formGroup]="form" uk-grid>
<div input [formInput]="form.get('name')" class="uk-width-1-2@m" placeholder="Title"></div> <div input [formInput]="form.get('name')" class="uk-width-1-2@m" placeholder="Title"></div>
<div input [formInput]="form.get('visibility')" class="uk-width-1-2@m" placeholder="Status" <div *ngIf="showVisibility" input [formInput]="form.get('visibility')" class="uk-width-1-2@m" placeholder="Status"
[options]="stakeholderUtils.visibility" type="select"></div> [options]="stakeholderUtils.visibilities" type="select"></div>
<div input [formInput]="form.get('description')" placeholder="Description" type="textarea" rows="4"></div> <div input [formInput]="form.get('description')" placeholder="Description" type="textarea" rows="4"></div>
<div *ngIf="form.get('icon')" input [formInput]="form.get('icon')" placeholder="Icon(SVG)" type="textarea"></div> <div *ngIf="form.get('icon')" input [formInput]="form.get('icon')" placeholder="Icon(SVG)" type="textarea"></div>
</div> </div>

View File

@ -1,32 +1,32 @@
import { import {
AfterViewInit, AfterViewInit,
ChangeDetectorRef, ChangeDetectorRef,
Component, Inject, Component,
Inject,
OnDestroy, OnDestroy,
OnInit, PLATFORM_ID, OnInit,
PLATFORM_ID,
QueryList, QueryList,
ViewChild, ViewChild,
ViewChildren ViewChildren
} from '@angular/core'; } from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router'; import {ActivatedRoute, Router} from '@angular/router';
import {Title} from '@angular/platform-browser'; import {Title} from '@angular/platform-browser';
import {EnvProperties} from '../../utils/properties/env-properties';
import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../../monitor/entities/stakeholder"; import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../../monitor/entities/stakeholder";
import {StakeholderService} from "../../monitor/services/stakeholder.service"; import {StakeholderService} from "../../monitor/services/stakeholder.service";
import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {HelperFunctions} from "../../utils/HelperFunctions.class";
import {AlertModal} from "../../utils/modal/alert"; import {AlertModal} from "../../utils/modal/alert";
import {BehaviorSubject, Subject, Subscriber, Subscription} from "rxjs"; import {BehaviorSubject, Subject, Subscriber, Subscription} from "rxjs";
import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms"; import {UntypedFormBuilder, UntypedFormGroup, Validators} from "@angular/forms";
import {StakeholderUtils} from "../utils/indicator-utils";
import {StringUtils} from "../../utils/string-utils.class"; import {StringUtils} from "../../utils/string-utils.class";
import {IDeactivateComponent} from "../../utils/can-exit.guard"; import {IDeactivateComponent} from "../../utils/can-exit.guard";
import {LayoutService} from "../../dashboard/sharedComponents/sidebar/layout.service";
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
import {properties} from "src/environments/environment"; import {properties} from "src/environments/environment";
import {Session, User} from "../../login/utils/helper.class"; import {Session, User} from "../../login/utils/helper.class";
import {UserManagementService} from "../../services/user-management.service"; import {UserManagementService} from "../../services/user-management.service";
import {TransitionGroupComponent} from "../../utils/transition-group/transition-group.component"; import {TransitionGroupComponent} from "../../utils/transition-group/transition-group.component";
import {NotificationHandler} from "../../utils/notification-handler"; import {NotificationHandler} from "../../utils/notification-handler";
import {StakeholderBaseComponent} from "../utils/stakeholder-base.component";
declare var UIkit; declare var UIkit;
@ -34,12 +34,9 @@ declare var UIkit;
selector: 'topic', selector: 'topic',
templateUrl: './topic.component.html', templateUrl: './topic.component.html',
}) })
export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeactivateComponent { export class TopicComponent extends StakeholderBaseComponent implements OnInit, OnDestroy, AfterViewInit, IDeactivateComponent {
private topicSubscriptions: any[] = []; private topicSubscriptions: any[] = [];
private subscriptions: any[] = [];
public properties: EnvProperties = properties;
public offset: number; public offset: number;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public loading: boolean = false; public loading: boolean = false;
public stakeholder: Stakeholder; public stakeholder: Stakeholder;
public user: User; public user: User;
@ -84,15 +81,15 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
}; };
constructor( constructor(
private route: ActivatedRoute, protected _route: ActivatedRoute,
private router: Router, protected _router: Router,
private title: Title, protected _title: Title,
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
private stakeholderService: StakeholderService, private stakeholderService: StakeholderService,
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private layoutService: LayoutService, protected cdr: ChangeDetectorRef,
private cdr: ChangeDetectorRef,
@Inject(PLATFORM_ID) private platformId) { @Inject(PLATFORM_ID) private platformId) {
super();
} }
public ngOnInit() { public ngOnInit() {
@ -115,7 +112,7 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
this.subCategoryIndex = index; this.subCategoryIndex = index;
}); });
})); }));
this.subscriptions.push(this.route.params.subscribe(params => { this.subscriptions.push(this._route.params.subscribe(params => {
if (subscription) { if (subscription) {
subscription.unsubscribe(); subscription.unsubscribe();
} }
@ -136,7 +133,8 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
if (this.topicIndex === -1) { if (this.topicIndex === -1) {
this.navigateToError(); this.navigateToError();
} else { } else {
this.title.setTitle(stakeholder.name + " | Indicators"); this.title = stakeholder.name + " | Indicators"
this.setMetadata();
} }
} }
}); });
@ -146,7 +144,7 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
this.user = user; this.user = user;
})) }))
} }
ngAfterViewInit() { ngAfterViewInit() {
if(this.topics) { if(this.topics) {
let activeIndex = UIkit.nav(this.topics.element.nativeElement).items.findIndex(item => item.classList.contains('uk-open')); let activeIndex = UIkit.nav(this.topics.element.nativeElement).items.findIndex(item => item.classList.contains('uk-open'));
@ -163,16 +161,12 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
} }
public ngOnDestroy() { public ngOnDestroy() {
super.ngOnDestroy();
this.topicSubscriptions.forEach(value => { this.topicSubscriptions.forEach(value => {
if (value instanceof Subscriber) { if (value instanceof Subscriber) {
value.unsubscribe(); value.unsubscribe();
} }
}); });
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
} }
canExit(): boolean { canExit(): boolean {
@ -666,7 +660,7 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
} }
private navigateToError() { private navigateToError() {
this.router.navigate([this.properties.errorLink], {queryParams: {'page': this.router.url}}); this._router.navigate([this.properties.errorLink], {queryParams: {'page': this._router.url}});
} }
get isCurator(): boolean { get isCurator(): boolean {
@ -714,8 +708,8 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
this.editModal.cancel(); this.editModal.cancel();
NotificationHandler.rise(message); NotificationHandler.rise(message);
if (redirect) { if (redirect) {
this.router.navigate(['../' + saveElement.alias], { this._router.navigate(['../' + saveElement.alias], {
relativeTo: this.route relativeTo: this._route
}); });
} }
}, error => { }, error => {
@ -758,8 +752,8 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
} }
back() { back() {
this.router.navigate(['../'], { this._router.navigate(['../'], {
relativeTo: this.route relativeTo: this._route
}); });
} }
@ -774,19 +768,6 @@ export class TopicComponent implements OnInit, OnDestroy, AfterViewInit, IDeacti
return this.type; return this.type;
} }
} }
public get isSmallScreen() {
return this.layoutService.isSmallScreen;
}
public get open() {
return this.layoutService.open;
}
public toggleOpen(event: MouseEvent) {
event.preventDefault();
this.layoutService.setOpen(!this.open);
}
public openVisibilityModal(index: number, visibility: Visibility, type: any) { public openVisibilityModal(index: number, visibility: Visibility, type: any) {
this.index = index; this.index = index;

View File

@ -7,11 +7,9 @@ import {
IndicatorPathType, IndicatorPathType,
IndicatorType, IndicatorType,
SourceType, SourceType,
Stakeholder, Stakeholder, SubCategory,
StakeholderEntities, Topic,
SubCategory, Visibility,
Topic, stakeholderTypes,
Visibility
} from "../../monitor/entities/stakeholder"; } from "../../monitor/entities/stakeholder";
import {AbstractControl, ValidatorFn, Validators} from "@angular/forms"; import {AbstractControl, ValidatorFn, Validators} from "@angular/forms";
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
@ -19,35 +17,72 @@ 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";
export class StakeholderUtils { class Entities {
stakeholder = 'Dashboard';
statuses: Option[] = [ funder = 'Funder';
{value: 'PUBLIC', label: 'Public'}, ri = 'Research Initiative';
{value: 'RESTRICTED', label: 'Restricted'}, organization = 'Research Institution';
{value: 'PRIVATE', label: 'Private'} project = 'Project';
country = 'National';
stakeholders = 'Dashboards';
funders = 'Funders';
ris = 'Research Initiatives';
organizations = 'Research Institutions';
projects = 'Projects';
}
export class StakeholderConfiguration {
public static ENTITIES: Entities = new Entities();
public static TYPES: Option[] = [
{value: 'funder', label: StakeholderConfiguration.ENTITIES.funder},
{value: 'ri', label: StakeholderConfiguration.ENTITIES.ri},
{value: 'organization', label: StakeholderConfiguration.ENTITIES.organization},
{value: 'project', label: StakeholderConfiguration.ENTITIES.project}
]; ];
public static LOCALES: Option[] = [
types: Option[] = [ {value: "en", label: 'English'},
...stakeholderTypes {value: "eu", label: 'Europe'}
]; ];
public static FUNDER_TYPES: Option[] = [];
visibility: Option[] = [ public static VISIBILITIES: Option[] = [
{icon: 'earth', value: "PUBLIC", label: 'Public'}, {icon: 'earth', value: "PUBLIC", label: 'Public'},
{icon: 'restricted', value: "RESTRICTED", label: 'Restricted'}, {icon: 'restricted', value: "RESTRICTED", label: 'Restricted'},
{icon: 'incognito', value: "PRIVATE", label: 'Private'}, {icon: 'incognito', value: "PRIVATE", label: 'Private'},
]; ];
}
locales: Option[] = [
{value: "en", label: 'English'}, export class StakeholderUtils {
{value: "eu", label: 'Europe'} get entities() {
]; return StakeholderConfiguration.ENTITIES;
}
visibilityIcon: Map<Visibility, string> = new Map<Visibility, string>([
["PUBLIC", 'earth'], get types() {
["PRIVATE", 'incognito'], return StakeholderConfiguration.TYPES
["RESTRICTED", 'restricted'] }
]);
get funderTypes() {
return StakeholderConfiguration.FUNDER_TYPES;
}
get locales() {
return StakeholderConfiguration.LOCALES;
}
get visibilities() {
return StakeholderConfiguration.VISIBILITIES;
}
visibilityIcon: Map<Visibility, string> = new Map<Visibility, string>(this.visibilities.map(option => [option.value, option.icon]));
defaultValue(options: Option[]) {
return options.length === 1?options[0].value:null;
}
showField(options: Option[]) {
return options.length > 1;
}
getTypesByUserRoles(user, id: string = null): Option[] { getTypesByUserRoles(user, id: string = null): Option[] {
let types = []; let types = [];
for (let type of this.types) { for (let type of this.types) {
@ -57,7 +92,7 @@ export class StakeholderUtils {
} }
return types; return types;
} }
public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[], isDefault: boolean = false): Stakeholder { public createFunderFromDefaultProfile(funder: Stakeholder, defaultTopics: Topic[], isDefault: boolean = false): Stakeholder {
funder.topics = HelperFunctions.copy(defaultTopics); funder.topics = HelperFunctions.copy(defaultTopics);
for (let topic of funder.topics) { for (let topic of funder.topics) {
@ -105,36 +140,36 @@ export class StakeholderUtils {
indicator._id = null; indicator._id = null;
} }
} }
} }
category.subCategories = subTokeep; category.subCategories = subTokeep;
} }
} }
return funder; return funder;
} }
aliasValidatorString(elements: string[]): ValidatorFn { aliasValidatorString(elements: string[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: string } | null => { return (control: AbstractControl): { [key: string]: string } | null => {
if (control.value && elements.find(element => if (control.value && elements.find(element =>
element === control.value element === control.value
)) { )) {
return {'error': 'Alias already in use'}; return {'error': 'Alias already in use'};
} }
return null; return null;
} }
} }
aliasValidator(elements: any[]): ValidatorFn { aliasValidator(elements: any[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: string } | null => { return (control: AbstractControl): { [key: string]: string } | null => {
if (control.value && elements.find(element => if (control.value && elements.find(element =>
element.alias === control.value element.alias === control.value
)) { )) {
return {'error': 'Alias already in use'}; return {'error': 'Alias already in use'};
} }
return null; return null;
} }
} }
generateAlias(name: string): string { generateAlias(name: string): string {
let alias = name.toLowerCase(); let alias = name.toLowerCase();
while (alias.includes('/') || alias.includes(' ')) { while (alias.includes('/') || alias.includes(' ')) {
@ -147,7 +182,7 @@ export class StakeholderUtils {
} }
export class IndicatorUtils { export class IndicatorUtils {
allChartTypes: Option[] = [ allChartTypes: Option[] = [
{value: 'pie', label: 'Pie'}, {value: 'pie', label: 'Pie'},
{value: 'table', label: 'Table'}, {value: 'table', label: 'Table'},
@ -163,64 +198,64 @@ export class IndicatorUtils {
{value: 'medium', label: 'Medium'}, {value: 'medium', label: 'Medium'},
{value: 'large', label: 'Large'} {value: 'large', label: 'Large'}
]; ];
allSourceTypes: Option[] = [ allSourceTypes: Option[] = [
{value: 'search', label: 'Search'}, {value: 'search', label: 'Search'},
{value: 'statistics', label: 'Statistics'}, {value: 'statistics', label: 'Statistics'},
{value: 'stats-tool', label: 'Statistics tool'} {value: 'stats-tool', label: 'Statistics tool'}
]; ];
formats: Option[] = [ formats: Option[] = [
{value: "NUMBER", label: "Number"}, {value: "NUMBER", label: "Number"},
{value: "PERCENTAGE", label: "Percentage"} {value: "PERCENTAGE", label: "Percentage"}
]; ];
sourceTypes: Option[] = [ sourceTypes: Option[] = [
{value: 'stats-tool', label: 'Statistics tool'} {value: 'stats-tool', label: 'Statistics tool'}
]; ];
isActive: Option[] = [ isActive: Option[] = [
{icon: 'brightness_1', iconClass: '', value: true, label: 'Active'}, {icon: 'brightness_1', iconClass: '', value: true, label: 'Active'},
{icon: 'brightness_1', value: false, label: 'Inactive'}, {icon: 'brightness_1', value: false, label: 'Inactive'},
]; ];
parametersValidators: Map<string, any> = new Map<string, any>([ parametersValidators: Map<string, any> = new Map<string, any>([
['start_year', [Validators.required, Validators.pattern('^\\d+$')]], ['start_year', [Validators.required, Validators.pattern('^\\d+$')]],
['end_year', [Validators.required, Validators.pattern('^\\d+$')]] ['end_year', [Validators.required, Validators.pattern('^\\d+$')]]
]); ]);
ignoredParameters = ['index_name', 'index_id', 'index_shortName']; ignoredParameters = ['index_name', 'index_id', 'index_shortName'];
statsProfileParameter = 'profile'; statsProfileParameter = 'profile';
numberSources: Map<SourceType, string[]> = new Map<SourceType, string[]>(); numberSources: Map<SourceType, string[]> = new Map<SourceType, string[]>();
chartSources: Map<SourceType, string[]> = new Map<SourceType, string[]>(); chartSources: Map<SourceType, string[]> = new Map<SourceType, string[]>();
constructor() { constructor() {
this.numberSources.set('statistics', [properties.statisticsAPIURL]); this.numberSources.set('statistics', [properties.statisticsAPIURL]);
this.numberSources.set('search', [properties.searchAPIURLLAst]); this.numberSources.set('search', [properties.searchAPIURLLAst]);
this.numberSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); this.numberSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/", "https://beta.services.openaire.eu/stats-tool/", "https://services.openaire.eu/stats-tool/", "https://services.openaire.eu/monitor-stats-tool/"]);
this.chartSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/","https://beta.services.openaire.eu/stats-tool/","https://services.openaire.eu/stats-tool/","https://services.openaire.eu/monitor-stats-tool/"]); this.chartSources.set('stats-tool', [properties.monitorStatsFrameUrl, "http://marilyn.athenarc.gr:8080/stats-api/", "http://88.197.53.71:8080/stats-api/", "https://stats.madgik.di.uoa.gr/stats-api/", "https://beta.services.openaire.eu/stats-tool/", "https://services.openaire.eu/stats-tool/", "https://services.openaire.eu/monitor-stats-tool/"]);
this.chartSources.set('old', [properties.statisticsFrameAPIURL]); this.chartSources.set('old', [properties.statisticsFrameAPIURL]);
this.chartSources.set('image', [""]); this.chartSources.set('image', [""]);
} }
getSourceType(source:string): SourceType{ getSourceType(source: string): SourceType {
let sourceType: SourceType = 'search'; let sourceType: SourceType = 'search';
this.numberSources.forEach((values, key) => { this.numberSources.forEach((values, key) => {
if(key == source) { if (key == source) {
sourceType = key; sourceType = key;
} }
}); });
return sourceType; return sourceType;
} }
getChartUrl(source: SourceType, url: string): string { getChartUrl(source: SourceType, url: string): string {
return this.chartSources.get(source)[0] + url; return this.chartSources.get(source)[0] + url;
} }
getNumberUrl(source: SourceType, url: string): string { getNumberUrl(source: SourceType, url: string): string {
return this.numberSources.get(this.getSourceType(source))[0] + url; return this.numberSources.get(this.getSourceType(source))[0] + url;
} }
getNumberSource(url: string): SourceType { getNumberSource(url: string): SourceType {
let source: SourceType = 'search'; let source: SourceType = 'search';
this.numberSources.forEach((values, key) => { this.numberSources.forEach((values, key) => {
@ -232,7 +267,7 @@ export class IndicatorUtils {
}); });
return source; return source;
} }
getChartSource(url: string): SourceType { getChartSource(url: string): SourceType {
let source: SourceType = 'image'; let source: SourceType = 'image';
this.chartSources.forEach((values, key) => { this.chartSources.forEach((values, key) => {
@ -244,7 +279,7 @@ export class IndicatorUtils {
}); });
return source; return source;
} }
getChartTypes(initialType) { getChartTypes(initialType) {
let types: Option[] = []; let types: Option[] = [];
if (this.basicChartTypes.indexOf(initialType) != -1) { if (this.basicChartTypes.indexOf(initialType) != -1) {
@ -265,7 +300,7 @@ export class IndicatorUtils {
return this.allChartTypes; return this.allChartTypes;
} }
} }
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 (stakeholder.statsProfile) {
@ -289,7 +324,7 @@ export class IndicatorUtils {
if (key == "index_shortName") { if (key == "index_shortName") {
replacedValue = stakeholder.index_shortName.toLowerCase(); 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)
}); });
} }
@ -307,7 +342,7 @@ export class IndicatorUtils {
} }
if (startYear && indicatorPath.filters["start_year"]) { if (startYear && indicatorPath.filters["start_year"]) {
let newJsonObject = JSON.parse(replacedUrl); let newJsonObject = JSON.parse(replacedUrl);
for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) { if (!queries["query"]["filters"] || queries["query"]["filters"].length == 0) {
queries["query"]["filters"] = []; queries["query"]["filters"] = [];
@ -328,7 +363,7 @@ export class IndicatorUtils {
} }
replacedUrl = JSON.stringify(newJsonObject); replacedUrl = JSON.stringify(newJsonObject);
} }
} }
//For numbers (e.g. from stats-api , search service, etc) //For numbers (e.g. from stats-api , search service, etc)
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) {
@ -342,7 +377,7 @@ 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): string { public getFullUrlWithFilters(stakeholder: Stakeholder, indicatorPath: IndicatorPath, fundingL0: string = null, startYear: string = null, endYear: string = null, coFunded: boolean = false): string {
indicatorPath.filtersApplied = 0; indicatorPath.filtersApplied = 0;
let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url; let replacedUrl = indicatorPath.chartObject ? indicatorPath.chartObject : indicatorPath.url;
@ -371,7 +406,7 @@ export class IndicatorUtils {
if (key == "index_shortName") { if (key == "index_shortName") {
replacedValue = stakeholder.index_shortName.toLowerCase(); 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)
}); });
} }
@ -403,7 +438,7 @@ export class IndicatorUtils {
indicatorPath.filtersApplied += filterResults.filtersApplied; indicatorPath.filtersApplied += filterResults.filtersApplied;
} }
} }
//For numbers //For numbers
if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) { if (replacedUrl.indexOf(ChartHelper.prefix + 'index_id' + ChartHelper.suffix) != -1) {
replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id)); replacedUrl = replacedUrl.split(ChartHelper.prefix + 'index_id' + ChartHelper.suffix).join(encodeURIComponent(stakeholder.index_id));
@ -416,9 +451,9 @@ export class IndicatorUtils {
} }
//Check apply enhancements return this.applySchemaEnhancements( ..); //Check apply enhancements return this.applySchemaEnhancements( ..);
return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl); return (indicatorPath.chartObject ? indicatorPath.url + encodeURIComponent(replacedUrl) : replacedUrl);
} }
private addFilter(replacedUrl, filterType: FilterType, filterValue) { private addFilter(replacedUrl, filterType: FilterType, filterValue) {
let newJsonObject = JSON.parse(replacedUrl); let newJsonObject = JSON.parse(replacedUrl);
let filterApplied: boolean = false; let filterApplied: boolean = false;
@ -426,7 +461,7 @@ export class IndicatorUtils {
for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) { for (let queries of this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)] : newJsonObject[this.getDescriptionObjectName(newJsonObject)]) {
/*Chart with Named Queries*/ /*Chart with Named Queries*/
if (queries["query"]["name"] && !queries["query"]["select"]) { if (queries["query"]["name"] && !queries["query"]["select"]) {
if (queries["query"]["name"].indexOf("monitor.") == -1 || !queries["query"]["parameters"]) { if (queries["query"]["name"].indexOf("monitor.") == -1 || !queries["query"]["parameters"]) {
continue; continue;
} }
@ -537,7 +572,7 @@ export class IndicatorUtils {
} }
return {"url": JSON.stringify(newJsonObject), "filtersApplied": (filterApplied) ? 1 : 0}; return {"url": JSON.stringify(newJsonObject), "filtersApplied": (filterApplied) ? 1 : 0};
} }
isComparingChart(newJsonObject, filter,) { isComparingChart(newJsonObject, filter,) {
let queriesCount = this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)].length : newJsonObject[this.getDescriptionObjectName(newJsonObject)].length; let queriesCount = this.getQueryObjectName(newJsonObject) ? newJsonObject[this.getDescriptionObjectName(newJsonObject)][this.getQueryObjectName(newJsonObject)].length : newJsonObject[this.getDescriptionObjectName(newJsonObject)].length;
let values = []; let values = [];
@ -554,10 +589,10 @@ 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, addParameters: boolean = true): 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;
@ -573,7 +608,7 @@ export class IndicatorUtils {
}); });
return indicator; return indicator;
} }
generateIndicatorByNumberUrl(source: SourceType, url: string, stakeholder: Stakeholder, jsonPath = [], sourceServices: string[] = []): IndicatorPath { generateIndicatorByNumberUrl(source: SourceType, url: string, stakeholder: Stakeholder, jsonPath = [], sourceServices: string[] = []): IndicatorPath {
let indicatorPath = new IndicatorPath(null, source, url, null, jsonPath); let indicatorPath = new IndicatorPath(null, source, url, null, jsonPath);
if (source === 'stats-tool') { if (source === 'stats-tool') {
@ -611,7 +646,7 @@ export class IndicatorUtils {
} }
return indicatorPath; return indicatorPath;
} }
generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder: Stakeholder): IndicatorPath { generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder: Stakeholder): IndicatorPath {
let indicatorPath = new IndicatorPath(type, source, null, null, []); let indicatorPath = new IndicatorPath(type, source, null, null, []);
try { try {
@ -621,13 +656,13 @@ export class IndicatorUtils {
indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]); indicatorPath.chartObject = decodeURIComponent(url.split("json=")[1]);
let chart = JSON.parse(indicatorPath.chartObject); let chart = JSON.parse(indicatorPath.chartObject);
if (indicatorPath.url == "chart?json=") { if (indicatorPath.url == "chart?json=") {
if (chart["library"] && (chart["library"] == "HighCharts" || chart["library"] == "eCharts" || chart["library"] == "HighMaps")) { if (chart["library"] && (chart["library"] == "HighCharts" || chart["library"] == "eCharts" || chart["library"] == "HighMaps")) {
indicatorPath.type = this.extractType(chart, indicatorPath); indicatorPath.type = this.extractType(chart, indicatorPath);
} else { } else {
indicatorPath.type = this.defaultChartType; indicatorPath.type = this.defaultChartType;
} }
this.extractTitle(chart, indicatorPath); this.extractTitle(chart, indicatorPath);
this.extractSubTitle(chart, indicatorPath); this.extractSubTitle(chart, indicatorPath);
this.extractXTitle(chart, indicatorPath); this.extractXTitle(chart, indicatorPath);
@ -667,7 +702,7 @@ export class IndicatorUtils {
} }
return indicatorPath; return indicatorPath;
} }
private getQueryObjectName(obj) { private getQueryObjectName(obj) {
if ((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queriesInfo")) { if ((obj[this.getDescriptionObjectName(obj)]).hasOwnProperty("queriesInfo")) {
return "queriesInfo"; return "queriesInfo";
@ -675,7 +710,7 @@ export class IndicatorUtils {
return "queries"; return "queries";
} }
} }
private getDescriptionObjectName(obj) { private getDescriptionObjectName(obj) {
if (obj.hasOwnProperty("mapDescription")) { if (obj.hasOwnProperty("mapDescription")) {
return "mapDescription"; return "mapDescription";
@ -687,7 +722,7 @@ export class IndicatorUtils {
return "series"; return "series";
} }
} }
private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType { private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType {
let type = (obj[this.getDescriptionObjectName(obj)] && obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"]) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"] : ""; let type = (obj[this.getDescriptionObjectName(obj)] && obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"]) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)][0]["type"] : "";
if (this.basicChartTypes.indexOf(type) == -1) { if (this.basicChartTypes.indexOf(type) == -1) {
@ -698,13 +733,13 @@ export class IndicatorUtils {
} }
return type; return type;
} }
private extractStakeHolders(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractStakeHolders(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
this.extractFunder(obj, indicatorPath, stakeholder); this.extractFunder(obj, indicatorPath, stakeholder);
this.extractRI(obj, indicatorPath, stakeholder); this.extractRI(obj, indicatorPath, stakeholder);
this.extractOrganization(obj, indicatorPath, stakeholder); this.extractOrganization(obj, indicatorPath, stakeholder);
} }
private extractFunder(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractFunder(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
if (stakeholder.type != "funder") { if (stakeholder.type != "funder") {
return; return;
@ -733,7 +768,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractRI(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractRI(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
if (stakeholder.type != "ri") { if (stakeholder.type != "ri") {
return; return;
@ -758,7 +793,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractOrganization(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) { private extractOrganization(obj, indicatorPath: IndicatorPath, stakeholder: Stakeholder) {
// works for publication.project.organization.name // works for publication.project.organization.name
// and publication.organization.name // and publication.organization.name
@ -785,7 +820,7 @@ export class IndicatorUtils {
} }
} }
} }
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)]) {
@ -803,7 +838,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractEndYear(obj, indicatorPath: IndicatorPath) { private extractEndYear(obj, indicatorPath: IndicatorPath) {
let end_year; let end_year;
for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { for (let query of obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
@ -821,7 +856,7 @@ export class IndicatorUtils {
} }
} }
} }
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)]) {
@ -843,7 +878,7 @@ export class IndicatorUtils {
} else if (name.split('.')[0] == "monitor" && parameters.length > 0 && name.split('.')[1] == stakeholder.type) { } else if (name.split('.')[0] == "monitor" && parameters.length > 0 && name.split('.')[1] == stakeholder.type) {
// new parameterized queries // new parameterized queries
//monitor.{{type}}.{{queryname}}.{{param1 - id }}.{{param2 result-type}}.{{fl0}} --> params [start year, end year, id, result type, fl0] //monitor.{{type}}.{{queryname}}.{{param1 - id }}.{{param2 result-type}}.{{fl0}} --> params [start year, end year, id, result type, fl0]
let index = (name.split('.').slice(3).length + 2 == parameters.length) ? [2] : ((name.split('.').slice(3).length * 2 + 4 == parameters.length) ? [2, name.split('.').slice(3).length + 4] : [0]); let index = (name.split('.').slice(3).length + 2 == parameters.length) ? [2] : ((name.split('.').slice(3).length * 2 + 4 == parameters.length) ? [2, name.split('.').slice(3).length + 4] : [0]);
for (let i of index) { for (let i of index) {
if (name.split('.').length > 3 && name.split('.')[3] == "id") { if (name.split('.').length > 3 && name.split('.')[3] == "id") {
@ -861,7 +896,7 @@ export class IndicatorUtils {
} }
} }
} }
private extractDataTitle(obj, indicatorPath: IndicatorPath) { private extractDataTitle(obj, indicatorPath: IndicatorPath) {
let index = 0; let index = 0;
if (!obj[this.getDescriptionObjectName(obj)] || !obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) { if (!obj[this.getDescriptionObjectName(obj)] || !obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)]) {
@ -876,7 +911,7 @@ export class IndicatorUtils {
index++; index++;
} }
} }
private extractTitle(obj, indicatorPath: IndicatorPath) { private extractTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj[this.getDescriptionObjectName(obj)]["title"]) { if (obj[this.getDescriptionObjectName(obj)]["title"]) {
@ -888,7 +923,7 @@ export class IndicatorUtils {
} }
indicatorPath.parameters["title"] = title ? title : ""; indicatorPath.parameters["title"] = title ? title : "";
} }
private extractSubTitle(obj, indicatorPath: IndicatorPath) { private extractSubTitle(obj, indicatorPath: IndicatorPath) {
let subtitle = ""; let subtitle = "";
if (obj[this.getDescriptionObjectName(obj)]["subtitle"]) { if (obj[this.getDescriptionObjectName(obj)]["subtitle"]) {
@ -901,7 +936,7 @@ export class IndicatorUtils {
indicatorPath.parameters["subtitle"] = subtitle ? subtitle : ""; indicatorPath.parameters["subtitle"] = subtitle ? subtitle : "";
} }
} }
private extractXTitle(obj, indicatorPath: IndicatorPath) { private extractXTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]) { if (obj[this.getDescriptionObjectName(obj)]["xAxis"] && obj[this.getDescriptionObjectName(obj)]["xAxis"]["title"]) {
@ -916,7 +951,7 @@ export class IndicatorUtils {
} }
indicatorPath.parameters["xAxisTitle"] = title ? title : ""; indicatorPath.parameters["xAxisTitle"] = title ? title : "";
} }
private extractYTitle(obj, indicatorPath: IndicatorPath) { private extractYTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]) { if (obj[this.getDescriptionObjectName(obj)]["yAxis"] && obj[this.getDescriptionObjectName(obj)]["yAxis"]["title"]) {
@ -931,17 +966,17 @@ export class IndicatorUtils {
} }
indicatorPath.parameters["yAxisTitle"] = title ? title : ""; indicatorPath.parameters["yAxisTitle"] = title ? title : "";
} }
private extractOldToolTitle(obj, indicatorPath: IndicatorPath) { private extractOldToolTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj["title"]) { if (obj["title"]) {
title = obj["title"]; title = obj["title"];
obj["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix; obj["title"] = ChartHelper.prefix + "title" + ChartHelper.suffix;
indicatorPath.parameters["title"] = title; indicatorPath.parameters["title"] = title;
} }
} }
private extractOldToolXTitle(obj, indicatorPath: IndicatorPath) { private extractOldToolXTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj["xaxistitle"]) { if (obj["xaxistitle"]) {
@ -950,7 +985,7 @@ export class IndicatorUtils {
indicatorPath.parameters["xAxisTitle"] = title; indicatorPath.parameters["xAxisTitle"] = title;
} }
} }
private extractOldToolYTitle(obj, indicatorPath: IndicatorPath) { private extractOldToolYTitle(obj, indicatorPath: IndicatorPath) {
let title = ""; let title = "";
if (obj["fieldsheaders"]) { if (obj["fieldsheaders"]) {
@ -963,11 +998,11 @@ export class IndicatorUtils {
indicatorPath.parameters["yAxisTitle"] = title; indicatorPath.parameters["yAxisTitle"] = title;
} }
} }
public checkForSchemaEnhancements(url: string): boolean { public checkForSchemaEnhancements(url: string): boolean {
return url != this.applySchemaEnhancements(url); return url != this.applySchemaEnhancements(url);
} }
public applySchemaEnhancements(url: string): string { public applySchemaEnhancements(url: string): string {
let resultEnhancements = [ let resultEnhancements = [
[".project.acronym", ".project acronym"], [".project.acronym", ".project acronym"],
@ -986,7 +1021,7 @@ export class IndicatorUtils {
} }
} }
} }
if (url.split('json=').length > 1) { if (url.split('json=').length > 1) {
let obj = JSON.parse(decodeURIComponent(url.split('json=')[1])); let obj = JSON.parse(decodeURIComponent(url.split('json=')[1]));
for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) { for (let query of this.getQueryObjectName(obj) ? obj[this.getDescriptionObjectName(obj)][this.getQueryObjectName(obj)] : obj[this.getDescriptionObjectName(obj)]) {

View File

@ -0,0 +1,35 @@
import {Directive} from "@angular/core";
import {BaseComponent} from "../../sharedComponents/base/base.component";
import {IndicatorUtils, StakeholderUtils} from "./indicator-utils";
@Directive()
export abstract class StakeholderBaseComponent extends BaseComponent {
stakeholderUtils: StakeholderUtils = new StakeholderUtils();
get entities() {
return this.stakeholderUtils.entities;
}
get showVisibility() {
return this.stakeholderUtils.showField(this.stakeholderUtils.visibilities);
}
get showType() {
return this.stakeholderUtils.showField(this.stakeholderUtils.types);
}
get showFunderType() {
return this.stakeholderUtils.showField(this.stakeholderUtils.funderTypes);
}
get showLocale() {
return this.stakeholderUtils.showField(this.stakeholderUtils.locales);
}
}
@Directive()
export abstract class IndicatorStakeholderBaseComponent extends StakeholderBaseComponent {
indicatorUtils: IndicatorUtils = new IndicatorUtils();
}

View File

@ -1,7 +1,6 @@
import {SafeResourceUrl} from "@angular/platform-browser"; import {SafeResourceUrl} from "@angular/platform-browser";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Session, User} from "../../login/utils/helper.class"; import {Session, User} from "../../login/utils/helper.class";
import {Option} from "../../sharedComponents/input/input.component";
export const ChartHelper = { export const ChartHelper = {
prefix: "((__", prefix: "((__",
@ -19,6 +18,7 @@ export type Visibility = 'PUBLIC' | 'PRIVATE' | 'RESTRICTED';
export class Stakeholder { export class Stakeholder {
_id: string; _id: string;
type: StakeholderType; type: StakeholderType;
funderType: string;
name: string; name: string;
index_id; index_id;
index_name: string; index_name: string;
@ -37,7 +37,7 @@ export class Stakeholder {
description: string; description: string;
topics: any[]; topics: any[];
constructor(_id: string, type: StakeholderType, index_id, 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) {
this._id = _id; this._id = _id;
this.type = type; this.type = type;
this.index_id = index_id; this.index_id = index_id;
@ -297,6 +297,11 @@ export class IndicatorFilterUtils {
} }
} }
/**
* @deprecated
*
* TODO: Remove after merge with develop
* */
export enum StakeholderEntities { export enum StakeholderEntities {
STAKEHOLDER = 'Dashboard', STAKEHOLDER = 'Dashboard',
FUNDER = 'Funder', FUNDER = 'Funder',
@ -311,10 +316,3 @@ export enum StakeholderEntities {
ORGANIZATIONS = 'Research Institutions', ORGANIZATIONS = 'Research Institutions',
PROJECTS = 'Projects' PROJECTS = 'Projects'
} }
export let stakeholderTypes: Option[] = [
{value: 'funder', label: StakeholderEntities.FUNDER},
{value: 'ri', label: StakeholderEntities.RI},
{value: 'organization', label: StakeholderEntities.ORGANIZATION},
{value: 'project', label: StakeholderEntities.PROJECT}
];

View File

@ -5,7 +5,7 @@ import {Meta, Title} from "@angular/platform-browser";
import {SEOService} from "../../sharedComponents/SEO/SEO.service"; import {SEOService} from "../../sharedComponents/SEO/SEO.service";
import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component"; import {Breadcrumb} from "../../utils/breadcrumbs/breadcrumbs.component";
import {Subscriber} from "rxjs"; import {Subscriber} from "rxjs";
import {StakeholderEntities} from "../entities/stakeholder"; import {StakeholderBaseComponent} from "../../monitor-admin/utils/stakeholder-base.component";
@Component({ @Component({
selector: 'indicator-themes-page', selector: 'indicator-themes-page',
@ -54,9 +54,9 @@ import {StakeholderEntities} from "../entities/stakeholder";
This is the current set of indicator themes we cover. Well keep enriching it as new requests and data are coming into the <a href="https://graph.openaire.eu" class="text-graph" target="_blank">OpenAIRE Graph</a>. We are at your disposal, should you have any recommendations! This is the current set of indicator themes we cover. Well keep enriching it as new requests and data are coming into the <a href="https://graph.openaire.eu" class="text-graph" target="_blank">OpenAIRE Graph</a>. We are at your disposal, should you have any recommendations!
</p> </p>
<p> <p>
Check out the indicator pages (for <a [routerLink]="['../funder']" [relativeTo]="route" class="uk-text-lowercase">{{entities.FUNDERS}}</a>, Check out the indicator pages (for <a [routerLink]="['../funder']" [relativeTo]="route" class="uk-text-lowercase">{{entities.funders}}</a>,
<a [routerLink]="['../organization']" [relativeTo]="route" class="uk-text-lowercase">{{entities.ORGANIZATIONS}}</a> and <a [routerLink]="['../organization']" [relativeTo]="route" class="uk-text-lowercase">{{entities.organizations}}</a> and
<a [routerLink]="['../ri']" [relativeTo]="route" class="uk-text-lowercase">{{entities.RIS}}</a>) <a [routerLink]="['../ri']" [relativeTo]="route" class="uk-text-lowercase">{{entities.ris}}</a>)
for the specific indicators for each type of dashboard, and the <a [routerLink]="['../../methodology']" [relativeTo]="route">methodology and terminology</a> page on how we produce the metrics. for the specific indicators for each type of dashboard, and the <a [routerLink]="['../../methodology']" [relativeTo]="route">methodology and terminology</a> page on how we produce the metrics.
</p> </p>
</div> </div>
@ -65,44 +65,24 @@ import {StakeholderEntities} from "../entities/stakeholder";
</div> </div>
` `
}) })
export class IndicatorThemesComponent implements OnInit, OnDestroy { export class IndicatorThemesComponent extends StakeholderBaseComponent implements OnInit {
private subscriptions: any[] = [];
public properties = properties;
public entities = StakeholderEntities;
public breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'Resources - Themes'}]; public breadcrumbs: Breadcrumb[] = [{name: 'home', route: '/'}, {name: 'Resources - Themes'}];
constructor(private router: Router, constructor(protected _router: Router,
private meta: Meta, protected _meta: Meta,
private title: Title, protected _title: Title,
private seoService: SEOService, protected seoService: SEOService,
public route: ActivatedRoute) { protected _route: ActivatedRoute) {
super();
} }
ngOnInit() { ngOnInit() {
this.subscriptions.push(this.route.params.subscribe(params => { this.subscriptions.push(this._route.params.subscribe(params => {
const description = "Monitor | Indicator Themes"; this.title = "Monitor | Indicator Themes";
const title = "Monitor | Indicator Themes"; this.description = "Monitor | Indicator Themes";
this.metaTags(title, description); this.setMetadata();
this.breadcrumbs[0].route = '/' + (params['stakeholder']?params['stakeholder']:''); this.breadcrumbs[0].route = '/' + (params['stakeholder']?params['stakeholder']:'');
this.breadcrumbs[0].name = (params['stakeholder']?'dashboard':'home'); this.breadcrumbs[0].name = (params['stakeholder']?'dashboard':'home');
})); }));
} }
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
subscription.unsubscribe();
}
});
}
metaTags(title, description) {
const url = properties.domain + properties.baseLink + this.router.url;
this.seoService.createLinkForCanonicalURL(url, false);
this.meta.updateTag({content: url}, "property='og:url'");
this.meta.updateTag({content: description}, "name='description'");
this.meta.updateTag({content: description}, "property='og:description'");
this.meta.updateTag({content: title}, "property='og:title'");
this.title.setTitle(title);
}
} }

View File

@ -1,12 +1,12 @@
import {Injectable} from "@angular/core"; import {Injectable} from "@angular/core";
import {MenuItem} from "../../sharedComponents/menu"; import {MenuItem} from "../../sharedComponents/menu";
import {Option} from "../../sharedComponents/input/input.component"; import {Option} from "../../sharedComponents/input/input.component";
import {StakeholderEntities} from "../entities/stakeholder";
import {from, Subscription} from "rxjs"; import {from, Subscription} from "rxjs";
import {HttpClient} from "@angular/common/http"; import {HttpClient} from "@angular/common/http";
import {properties} from "../../../../environments/environment"; import {properties} from "../../../../environments/environment";
import {Page} from "../../utils/entities/adminTool/page"; import {Page} from "../../utils/entities/adminTool/page";
import {map} from "rxjs/operators"; import {map} from "rxjs/operators";
import {StakeholderConfiguration} from "../../monitor-admin/utils/indicator-utils";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -16,12 +16,7 @@ export class ResourcesService {
private subscription: Subscription; private subscription: Subscription;
private routes = ResourcesService.types.map(type => '/indicators/' + type.value); private routes = ResourcesService.types.map(type => '/indicators/' + type.value);
public static readonly types: Option[] = [ public static readonly types: Option[] = StakeholderConfiguration.TYPES;
{value: 'funder', label: StakeholderEntities.FUNDERS},
{value: 'ri', label: StakeholderEntities.RIS},
{value: 'project', label: StakeholderEntities.PROJECTS},
{value: 'organization', label: StakeholderEntities.ORGANIZATIONS}
];
constructor(private http: HttpClient) { constructor(private http: HttpClient) {
} }

View File

@ -40,7 +40,7 @@ export class NotificationConfiguration {
<span *ngIf="mobile" class="uk-margin-right"> <span *ngIf="mobile" class="uk-margin-right">
<icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon> <icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon>
</span> </span>
<div class="uk-text-bold">Notifications</div> <span class="uk-text-bold">Notifications</span>
</h4> </h4>
<div class="uk-flex uk-flex-right@m uk-flex-center uk-padding uk-padding-remove-vertical"> <div class="uk-flex uk-flex-right@m uk-flex-center uk-padding uk-padding-remove-vertical">
<button [disabled]="unreadCount === 0" (click)="readAll()" class="uk-button uk-button-link">Mark As Read ({{unreadCount}})</button> <button [disabled]="unreadCount === 0" (click)="readAll()" class="uk-button uk-button-link">Mark As Read ({{unreadCount}})</button>
@ -75,7 +75,7 @@ export class NotificationConfiguration {
<span class="uk-margin-right"> <span class="uk-margin-right">
<icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon> <icon ratio="1.5" name="west" visuallyHidden="back" [flex]="true"></icon>
</span> </span>
<div *ngIf="notification.title" class="uk-text-bold">{{notification.title}}</div> <span *ngIf="notification.title" class="uk-text-bold">{{notification.title}}</span>
</h4> </h4>
<div class="uk-flex uk-flex-middle uk-margin-medium-bottom"> <div class="uk-flex uk-flex-middle uk-margin-medium-bottom">
<notification-user [name]="notification.name" [surname]="notification.surname" colorClass="uk-text-secondary" [outline]="true"></notification-user> <notification-user [name]="notification.name" [surname]="notification.surname" colorClass="uk-text-secondary" [outline]="true"></notification-user>

View File

@ -7,11 +7,12 @@ import {NotificationService} from "../notification.service";
import {Notification} from "../notifications"; import {Notification} from "../notifications";
import {InputComponent, Option} from "../../sharedComponents/input/input.component"; import {InputComponent, Option} from "../../sharedComponents/input/input.component";
import {NotificationHandler} from "../../utils/notification-handler"; import {NotificationHandler} from "../../utils/notification-handler";
import {BaseComponent} from "../../sharedComponents/base/base.component";
@Component({ @Component({
selector: '[notify-form]', selector: '[notify-form]',
template: ` template: `
<form *ngIf="user && form" [formGroup]="form"> <form *ngIf="user && form && properties.notificationsAPIURL" [formGroup]="form">
<ng-template [ngIf]="form.get('notify')"> <ng-template [ngIf]="form.get('notify')">
<label><input name="notify" type="checkbox" class="uk-checkbox" formControlName="notify"><span class="uk-margin-small-left">{{label}}</span></label> <label><input name="notify" type="checkbox" class="uk-checkbox" formControlName="notify"><span class="uk-margin-small-left">{{label}}</span></label>
<div [class.uk-hidden]="!form.get('notify').value" class="uk-position-relative uk-margin-medium-top"> <div [class.uk-hidden]="!form.get('notify').value" class="uk-position-relative uk-margin-medium-top">
@ -44,7 +45,7 @@ import {NotificationHandler} from "../../utils/notification-handler";
styleUrls: ['notify-form.component.less'], styleUrls: ['notify-form.component.less'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
}) })
export class NotifyFormComponent implements OnInit, OnDestroy { export class NotifyFormComponent extends BaseComponent implements OnInit {
@Input() @Input()
public label: string = 'Notify Managers'; public label: string = 'Notify Managers';
public form: UntypedFormGroup; public form: UntypedFormGroup;
@ -57,13 +58,13 @@ export class NotifyFormComponent implements OnInit, OnDestroy {
public focused: boolean = false; public focused: boolean = false;
@ViewChild('recipients', { static: false }) recipients: InputComponent; @ViewChild('recipients', { static: false }) recipients: InputComponent;
private notification: Notification; private notification: Notification;
private subscriptions: any[] = [];
public sending: boolean = false; public sending: boolean = false;
constructor(private fb: UntypedFormBuilder, constructor(private fb: UntypedFormBuilder,
private cdr: ChangeDetectorRef, private cdr: ChangeDetectorRef,
private userManagementService: UserManagementService, private userManagementService: UserManagementService,
private notificationService: NotificationService) { private notificationService: NotificationService) {
super();
} }
@Input() @Input()
@ -79,14 +80,6 @@ export class NotifyFormComponent implements OnInit, OnDestroy {
})); }));
} }
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscription) {
subscription.unsubscribe();
}
})
}
reset(message: string = null) { reset(message: string = null) {
if (!this.availableGroups) { if (!this.availableGroups) {
this.form = this.fb.group({ this.form = this.fb.group({
@ -162,16 +155,12 @@ export class NotifyFormComponent implements OnInit, OnDestroy {
} }
get message(): string { get message(): string {
if ((this.form.get('notify') && !this.form.get('notify').value) || (this.groupsAsFromArray && this.groupsAsFromArray.length === 0)) { if (!this.properties.notificationsAPIURL || (this.form.get('notify') && !this.form.get('notify').value) || (this.groupsAsFromArray && this.groupsAsFromArray.length === 0)) {
return null; return null;
} }
return this.form.get('message').value; return this.form.get('message').value;
} }
onFocus(event: boolean) {
this.focused = event;
}
focus(event) { focus(event) {
this.focused = true; this.focused = true;
event.stopPropagation(); event.stopPropagation();

View File

@ -43,7 +43,7 @@ export abstract class BaseComponent implements OnDestroy {
} }
/** /**
* Initialize router params and data (should be called in the constructor) * Initialize router params and data (should be called in the constructor of a component with router-outlet)
* */ * */
initRouterParams(route: ActivatedRoute = null) { initRouterParams(route: ActivatedRoute = null) {
if (route) { if (route) {
@ -55,6 +55,16 @@ export abstract class BaseComponent implements OnDestroy {
while (r.firstChild) { while (r.firstChild) {
r = r.firstChild; r = r.firstChild;
} }
let data = r.snapshot.data;
let params = r.snapshot.params;
let current = r.snapshot;
while (current.parent) {
data = {...current.parent.data, ...data};
params = {...current.parent.params, ...params};
current = current.parent;
}
r.snapshot.data = data;
r.snapshot.params = params;
this.paramsResolved = true; this.paramsResolved = true;
this.params.next(r.snapshot.params); this.params.next(r.snapshot.params);
this.data.next(r.snapshot.data); this.data.next(r.snapshot.data);

View File

@ -47,11 +47,13 @@ export interface StopRule {
@Component({ @Component({
selector: 'icon', selector: 'icon',
template: ` template: `
<span #svgIcon *ngIf="icon.data" class="uk-icon" [class.uk-preserve]="gradient || icon.preserveColor" [class.uk-flex]="flex" [ngClass]="customClass" [ngStyle]="style" [innerHTML]="icon.data | safeHtml"></span> <ng-container *ngIf="icon">
<span *ngIf="!icon.data && icon.name" [class.uk-flex]="flex" [ngClass]="customClass" [class.uk-display-inline-block]="!flex"> <span #svgIcon *ngIf="icon.data" class="uk-icon" [class.uk-preserve]="gradient || icon.preserveColor" [class.uk-flex]="flex" [ngClass]="customClass" [ngStyle]="style" [innerHTML]="icon.data | safeHtml"></span>
<span class="material-icons" [ngClass]="type?type:icon.type" [ngStyle]="style">{{icon.name}}</span> <span *ngIf="!icon.data && icon.name" [class.uk-flex]="flex" [ngClass]="customClass" [class.uk-display-inline-block]="!flex">
</span> <span class="material-icons" [ngClass]="type?type:icon.type" [ngStyle]="style">{{icon.name}}</span>
<span *ngIf="visuallyHidden" class="visually-hidden">{{visuallyHidden}}</span> </span>
<span *ngIf="visuallyHidden" class="visually-hidden">{{visuallyHidden}}</span>
</ng-container>
` `
}) })
export class IconsComponent implements AfterViewInit, OnChanges { export class IconsComponent implements AfterViewInit, OnChanges {
@ -149,7 +151,7 @@ export class IconsComponent implements AfterViewInit, OnChanges {
} }
initIcon() { initIcon() {
if(this.icon.data && this.svgIcon) { if(this.icon?.data && this.svgIcon) {
this.cdr.detectChanges(); this.cdr.detectChanges();
let svg: Element = this.svgIcon.nativeElement.getElementsByTagName('svg').item(0); let svg: Element = this.svgIcon.nativeElement.getElementsByTagName('svg').item(0);
if(!this.defaultSize && svg) { if(!this.defaultSize && svg) {

View File

@ -1,7 +1,7 @@
export type Environment = "development" | "test" | "beta" | "production"; export type Environment = "development" | "test" | "beta" | "production";
export type Dashboard = "explore" | "connect" | "monitor" | "aggregator" | "eosc" | "developers" | "faircore4eosc"; export type Dashboard = "explore" | "connect" | "monitor" | "aggregator" | "eosc" | "developers" | "faircore4eosc";
export type PortalType = "explore" | "connect" | "community" | "monitor" | "funder" | "ri" | "project" | "organization" | "aggregator" | "eosc" | "faircore4eosc"; export type PortalType = "explore" | "connect" | "community" | "monitor" | "funder" | "ri" | "project" | "organization" | "aggregator" | "eosc" | "faircore4eosc" | "irish";
export interface EnvProperties { export interface EnvProperties {
environment?: Environment; environment?: Environment;

View File

@ -1,9 +1,10 @@
import {UrlSegment} from '@angular/router'; import {UrlSegment} from '@angular/router';
import {AbstractControl, UntypedFormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms"; import {AbstractControl, UntypedFormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms";
import {Stakeholder, StakeholderEntities} from "../monitor/entities/stakeholder"; import {Stakeholder} from "../monitor/entities/stakeholder";
import {CommunityInfo} from "../connect/community/communityInfo"; import {CommunityInfo} from "../connect/community/communityInfo";
import {properties} from "../../../environments/environment"; import {properties} from "../../../environments/environment";
import {OpenaireEntities} from "./properties/searchFields"; import {OpenaireEntities} from "./properties/searchFields";
import {StakeholderConfiguration} from "../monitor-admin/utils/indicator-utils";
export class Dates { export class Dates {
public static yearMin = 1800; public static yearMin = 1800;
@ -524,13 +525,13 @@ export class StringUtils {
public static getStakeholderType(stakeholderType: string, plural: boolean = false): string { public static getStakeholderType(stakeholderType: string, plural: boolean = false): string {
if(stakeholderType == "funder") { if(stakeholderType == "funder") {
return plural ? StakeholderEntities.FUNDERS : StakeholderEntities.FUNDER; return plural ? StakeholderConfiguration.ENTITIES.funders : StakeholderConfiguration.ENTITIES.funders;
} else if(stakeholderType == "ri") { } else if(stakeholderType == "ri") {
return plural ? StakeholderEntities.RIS : StakeholderEntities.RI; return plural ?StakeholderConfiguration.ENTITIES.ris : StakeholderConfiguration.ENTITIES.ri;
} else if(stakeholderType == "organization") { } else if(stakeholderType == "organization") {
return plural ? StakeholderEntities.ORGANIZATIONS : StakeholderEntities.ORGANIZATION; return plural ? StakeholderConfiguration.ENTITIES.organizations : StakeholderConfiguration.ENTITIES.organization;
} else if(stakeholderType == "project") { } else if(stakeholderType == "project") {
return plural ? StakeholderEntities.PROJECTS : StakeholderEntities.PROJECT; return plural ? StakeholderConfiguration.ENTITIES.projects: StakeholderConfiguration.ENTITIES.project;
} }
return stakeholderType; return stakeholderType;
} }