[Monitor Dashboard]: Handle alias. There is a bug with observables, need to be checked

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-monitor-portal/trunk/monitor_dashboard@57831 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
Konstantinos Triantafyllou 2019-12-06 13:52:26 +00:00
parent 529c9ce933
commit 90b5ce8db1
12 changed files with 813 additions and 721 deletions

View File

@ -1,5 +1,5 @@
import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core'; import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
import {ActivatedRoute, NavigationEnd, RouteConfigLoadEnd, Router} from '@angular/router'; import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
import {EnvProperties} from './openaireLibrary/utils/properties/env-properties'; import {EnvProperties} from './openaireLibrary/utils/properties/env-properties';
import {EnvironmentSpecificService} from './openaireLibrary/utils/properties/environment-specific.service'; import {EnvironmentSpecificService} from './openaireLibrary/utils/properties/environment-specific.service';

View File

@ -163,7 +163,13 @@ export class HomeComponent implements OnInit, OnDestroy {
index_id: this.fb.control(this.stakeholder.index_id, Validators.required), index_id: this.fb.control(this.stakeholder.index_id, Validators.required),
index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required), index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required),
isDefaultProfile: this.fb.control(this.stakeholder.isDefaultProfile), isDefaultProfile: this.fb.control(this.stakeholder.isDefaultProfile),
alias: this.fb.control(this.stakeholder.alias, Validators.required), alias: this.fb.control(this.stakeholder.alias,
[
Validators.required,
this.stakeholderUtils.aliasValidator(
(this.stakeholder.isDefaultProfile) ? this.defaultStakeholders : this.stakeholders
)]
),
isPublic: this.fb.control(this.stakeholder.isPublic), isPublic: this.fb.control(this.stakeholder.isPublic),
isActive: this.fb.control(this.stakeholder.isActive), isActive: this.fb.control(this.stakeholder.isActive),
type: this.fb.control(this.stakeholder.type, Validators.required), type: this.fb.control(this.stakeholder.type, Validators.required),
@ -196,7 +202,7 @@ export class HomeComponent implements OnInit, OnDestroy {
public saveStakeholder() { public saveStakeholder() {
if (this.index === -1) { if (this.index === -1) {
if(!this.stakeholderFb.value.isDefaultProfile) { if (!this.stakeholderFb.value.isDefaultProfile) {
// this.stakeholderFb.setValue(this.stakeholderUtils. // this.stakeholderFb.setValue(this.stakeholderUtils.
// createFunderFromDefaultProfile(this.stakeholderFb.value, // createFunderFromDefaultProfile(this.stakeholderFb.value,
// this.defaultStakeholders.find( value => value.type === this.stakeholderFb.value.type).topics)); // this.defaultStakeholders.find( value => value.type === this.stakeholderFb.value.type).topics));

View File

@ -10,7 +10,7 @@ export class LayoutService {
/** /**
* Set this to true when sidebar items are ready. * Set this to true when sidebar items are ready.
*/ */
private openSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true); private openSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
/** /**
* Add hasSidebar: false on data of route config, if sidebar is not needed. * Add hasSidebar: false on data of route config, if sidebar is not needed.

View File

@ -13,7 +13,7 @@
[class.act_section]="item.open" [class.act_section]="item.open"
[title]="item.name" [title]="item.name"
[class.submenu_trigger]="item.items.length > 1"> [class.submenu_trigger]="item.items.length > 1">
<a *ngIf="item.items.length <= 1 && item.route" [routerLink]="!isTheActiveMenuItem(item)?item.route:null"> <a *ngIf="item.items.length <= 1" [routerLink]="(item.route && !isTheActiveMenuItem(item))?item.route:null">
<span *ngIf="item.icon" class="menu_icon"><i class="material-icons">{{item.icon}}</i></span> <span *ngIf="item.icon" class="menu_icon"><i class="material-icons">{{item.icon}}</i></span>
<span class="menu_title">{{item.name}}</span> <span class="menu_title">{{item.name}}</span>
</a> </a>

View File

@ -15,6 +15,7 @@ export class SideBarComponent implements OnInit {
constructor() {} constructor() {}
ngOnInit(): void { ngOnInit(): void {
console.log(this.items);
} }

View File

@ -1,175 +1,178 @@
<!--disable_transitions --> <!--disable_transitions -->
<div class="double-header stakeholderPage"> <div class="double-header stakeholderPage">
<div class=""> <div class="">
<div id="header_menu" class="uk-width-1-1"> <div id="header_menu" class="uk-width-1-1">
<nav class="uk-navbar"> <nav class="uk-navbar">
<div class="uk-navbar-left"> <div class="uk-navbar-left">
<img class="badge " <img class="badge "
src="assets/theme-assets/prototype_flag.svg" src="assets/theme-assets/prototype_flag.svg"
alt="BETA"> alt="BETA">
<a *ngIf="stakeholder" class="uk-logo uk-navbar-item ng-star-inserted uk-link uk-margin-small-top uk-margin-medium-left" <a *ngIf="stakeholder"
routerlink="/" class="uk-logo uk-navbar-item ng-star-inserted uk-link uk-margin-small-top uk-margin-medium-left"
routerlinkactive="uk-link" href="/"> routerlink="/"
<img *ngIf="stakeholder.logoUrl" [src]="stakeholder.logoUrl" class="uk-responsive-height"> routerlinkactive="uk-link" href="/">
<div *ngIf="!stakeholder.logoUrl"> <img *ngIf="stakeholder.logoUrl" [src]="stakeholder.logoUrl" class="uk-responsive-height">
{{stakeholder.index_name}} <div *ngIf="!stakeholder.logoUrl">
</div> {{stakeholder.index_name}}
</a> </div>
<div class="uk-margin-large-left uk-width-medium ng-star-inserted"> </a>
<div class=""> <div class="uk-margin-large-left uk-width-medium ng-star-inserted">
<!-- <div dashboard-input label="Search for..." [formInput]="keyword"></div>--> <div class="">
</div> <!-- <div dashboard-input label="Search for..." [formInput]="keyword"></div>-->
</div> </div>
</div>
<div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" class="uk-navbar-right uk-margin-right">
<!--<ul class="uk-navbar-nav">
<li class="uk-active">
<a class="uk-margin-remove-bottom "><span>Monitor</span></a>
</li>
<li>
<a class="uk-margin-remove-bottom ">Search</a>
</li>
<li>
<a class="uk-margin-remove-bottom ">Help</a>
</li>
</ul>-->
</div>
</nav>
</div>
</div>
<div class="sidebar_main_swipe header_full" [class.sidebar_main_active]="open">
<div id="header_main">
<nav class="uk-light">
<div class="main_logo_top">
<div *ngIf="stakeholder && stakeholder.index_name" class=" ">
<div class="uk-text-bold uk-h4 uk-margin-remove-bottom">{{stakeholder.index_name}}</div>
<div class="uk-h5 uk-margin-remove">Monitor Dashboard</div>
</div>
</div>
<a id="sidebar_main_toggle" (click)="toggleOpen()" class="sSwitch sSwitch_left uk-margin-left">
<span class="sSwitchIcon"></span>
</a>
<div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" class="uk-navbar-center">
<ul class="uk-navbar-nav">
<ng-template ngFor [ngForOf]="stakeholder.topics" let-topic let-i="index">
<li *ngIf="topic.isPublic && topic.isActive"
[ngClass]="(topic.alias === activeTopic.alias)?'uk-active':''">
<a (click)="navigateTo(stakeholder.alias, topic.alias)" class="uk-margin-remove-bottom uk-h4"
><span>{{topic.name}}</span></a>
</li>
</ng-template>
</ul>
</div>
</nav>
</div>
<dashboard-sidebar *ngIf="sideBar && stakeholder" [items]="sideBar.items"
[activeItem]="activeCategory?activeCategory.alias:null"
[activeSubItem]="activeSubCategory?activeSubCategory.alias:null" [showHeader]=false
></dashboard-sidebar>
<div *ngIf="activeSubCategory"
id="page_content" click-outside-or-esc targetId="page_content" [escClose]="false"
(clickOutside)="toggleOpen($event)">
<div id="page_content_inner">
<!-- <div>
Filters
<input class="uk-input uk-form-width-medium" placeholder="Funding Stream" type="text" name="fund_level_0"
[(ngModel)]="fundingL0">
<input class="uk-input uk-form-width-medium" placeholder="Start year" type="text" name="start_year"
[(ngModel)]="startYear">
<input class="uk-input uk-form-width-medium" placeholder="End year" type="text" name="end_year"
[(ngModel)]="endYear">
<button class="uk-button uk-button-primary" (click)="setIndicators()">Apply</button>
</div>-->
<h4 *ngIf="activeSubCategory.numbers.length > 0 ||activeSubCategory.charts.length > 0; else noIndicators "
class="uk-margin uk-margin-top uk-text-bold">Indicators
</h4>
<ng-template #noIndicators>
<div class="">
<div class="">
<div class="uk-h3">
No indicators available yet. Stay tuned!
</div>
</div>
</div>
<div *ngIf="activeSubCategory.description && activeSubCategory.description.length > 0 ||
activeCategory.description && activeCategory.description.length > 0 ||
activeTopic.description && activeTopic.description.length > 0"
class="">
<div class="">
<div class="uk-h5">
{{activeSubCategory.description && activeSubCategory.description.length > 0 ? activeSubCategory.description
:(activeCategory.description && activeCategory.description.length > 0 ? activeCategory.description :
(activeTopic.description && activeTopic.description.length > 0 ? activeTopic.description : ""))}}
</div>
</div>
</div>
</ng-template>
<div class="uk-grid uk-grid-medium uk-margin-bottom" uk-height-match="target: div.md-card">
<ng-template ngFor [ngForOf]="activeSubCategory.numbers" let-number let-i="index">
<div *ngIf="number.isActive && number.isPublic"
[class.uk-width-1-3@m]="number.width === 'small'"
[class.uk-width-1-2@m]="number.width === 'medium'"
[class.uk-width-1-1]="number.width === 'large'">
<div class="md-card"
[attr.uk-tooltip]="number.description">
<div class="md-card-content">
<span class="uk-text-muted uk-margin-bottom uk-h5">{{number.name}}</span>
<h2 *ngIf="numberResults.get(i)" class="uk-margin-remove">
<span>{{numberResults.get(i) | number}}</span>
</h2>
</div>
</div>
</div>
</ng-template>
</div>
<div class="uk-grid uk-grid-medium uk-margin-bottom uk-flex uk-flex-bottom "
uk-height-match="target: div > div > .chartTitle">
<ng-template ngFor [ngForOf]="activeSubCategory.charts" let-chart let-i="index">
<div *ngIf="chart.isActive && chart.isPublic && chartsActiveType.get(i)"
[class.uk-width-1-3@m]="chart.width === 'small'"
[class.uk-width-1-2@m]="chart.width === 'medium'"
[class.uk-width-1-1]="chart.width === 'large'">
<div class="indicatorBox">
<h4 class="uk-margin-bottom uk-margin-top chartTitle uk-flex uk-flex-bottom ">
<div>{{chart.name + " "}}</div>
</h4>
<div class="md-card" [attr.uk-tooltip]="chart.description">
<div class="md-card-content uk-text-center">
<div *ngIf="chart.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of chart.indicatorPaths;"
class="uk-button"
(click)="setActiveChart(i, indicatorPath.type)"
[class.uk-button-secondary]="chartsActiveType.get(i).url === indicatorPath.url">
{{indicatorPath.type}}
</button>
</div> </div>
<iframe *ngIf="chartsActiveType.get(i).source !== 'image'"
[src]="chartsActiveType.get(i).safeResourceUrl"
class="uk-width-1-1 uk-height-medium"></iframe>
<!-- {{chartsActiveType.get(i).safeResourceUrl}}-->
<img *ngIf="chartsActiveType.get(i).source === 'image'"
[src]="chartsActiveType.get(i).safeResourceUrl"
class="uk-width-1-1 uk-height-medium">
</div>
</div> </div>
</div>
</div> <div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic"
</ng-template> class="uk-navbar-right uk-margin-right">
<!--<ul class="uk-navbar-nav">
<li class="uk-active">
<a class="uk-margin-remove-bottom "><span>Monitor</span></a>
</li>
<li>
<a class="uk-margin-remove-bottom ">Search</a>
</li>
<li>
<a class="uk-margin-remove-bottom ">Help</a>
</li>
</ul>-->
</div>
</nav>
</div> </div>
</div>
</div> </div>
</div> <div class="sidebar_main_swipe header_full" [class.sidebar_main_active]="open">
<a id="style_switcher" class="" routerLinkActive="active" <div id="header_main">
[routerLink]="['/admin', this.stakeholder.alias]"> <nav class="uk-light">
<div id="style_switcher_toggle"><i class="material-icons">settings</i></div> <div class="main_logo_top">
</a> <div *ngIf="stakeholder && stakeholder.index_name" class=" ">
<div class="uk-text-bold uk-h4 uk-margin-remove-bottom">{{stakeholder.index_name}}</div>
<div class="uk-h5 uk-margin-remove">Monitor Dashboard</div>
</div>
</div>
<a id="sidebar_main_toggle" (click)="toggleOpen()" class="sSwitch sSwitch_left uk-margin-left">
<span class="sSwitchIcon"></span>
</a>
<div *ngIf="stakeholder && status === errorCodes.DONE && activeTopic" class="uk-navbar-center">
<ul class="uk-navbar-nav">
<ng-template ngFor [ngForOf]="stakeholder.topics" let-topic let-i="index">
<li *ngIf="topic.isPublic && topic.isActive"
[ngClass]="(topic.alias === activeTopic.alias)?'uk-active':''">
<a (click)="navigateTo(stakeholder.alias, topic.alias)"
class="uk-margin-remove-bottom uk-h4"
><span>{{topic.name}}</span></a>
</li>
</ng-template>
</ul>
</div>
</nav>
</div>
<dashboard-sidebar *ngIf="sideBar && stakeholder" [items]="sideBar.items"
[activeItem]="activeCategory?activeCategory.alias:null"
[activeSubItem]="activeSubCategory?activeSubCategory.alias:null" [showHeader]=false
></dashboard-sidebar>
<div id="page_content" click-outside-or-esc targetId="page_content" [escClose]="false"
(clickOutside)="toggleOpen($event)">
<div id="page_content_inner">
<!-- <div>
Filters
<input class="uk-input uk-form-width-medium" placeholder="Funding Stream" type="text" name="fund_level_0"
[(ngModel)]="fundingL0">
<input class="uk-input uk-form-width-medium" placeholder="Start year" type="text" name="start_year"
[(ngModel)]="startYear">
<input class="uk-input uk-form-width-medium" placeholder="End year" type="text" name="end_year"
[(ngModel)]="endYear">
<button class="uk-button uk-button-primary" (click)="setIndicators()">Apply</button>
</div>-->
<h4 *ngIf="activeSubCategory && (activeSubCategory.numbers.length > 0
|| activeSubCategory.charts.length > 0); else noIndicators"
class="uk-margin uk-margin-top uk-text-bold">Indicators
</h4>
<ng-template #noIndicators>
<div class="">
<div class="">
<div class="uk-h3">
No indicators available yet. Stay tuned!
</div>
</div>
</div>
<div *ngIf="(activeSubCategory && activeSubCategory.description && activeSubCategory.description.length > 0) ||
(activeCategory && activeCategory.description && activeCategory.description.length > 0) ||
(activeTopic && activeTopic.description && activeTopic.description.length > 0)"
class="">
<div class="">
<div class="uk-h5">
{{activeSubCategory.description && activeSubCategory.description.length > 0 ? activeSubCategory.description
: (activeCategory.description && activeCategory.description.length > 0 ? activeCategory.description :
(activeTopic.description && activeTopic.description.length > 0 ? activeTopic.description : ""))}}
</div>
</div>
</div>
</ng-template>
<div *ngIf="activeSubCategory" class="uk-grid uk-grid-medium uk-margin-bottom"
uk-height-match="target: div.md-card">
<ng-template ngFor [ngForOf]="activeSubCategory.numbers" let-number let-i="index">
<div *ngIf="number.isActive && number.isPublic"
[class.uk-width-1-3@m]="number.width === 'small'"
[class.uk-width-1-2@m]="number.width === 'medium'"
[class.uk-width-1-1]="number.width === 'large'">
<div class="md-card"
[attr.uk-tooltip]="number.description">
<div class="md-card-content">
<span class="uk-text-muted uk-margin-bottom uk-h5">{{number.name}}</span>
<h2 *ngIf="numberResults.get(i)" class="uk-margin-remove">
<span>{{numberResults.get(i) | number}}</span>
</h2>
</div>
</div>
</div>
</ng-template>
</div>
<div *ngIf="activeSubCategory" class="uk-grid uk-grid-medium uk-margin-bottom uk-flex uk-flex-bottom "
uk-height-match="target: div > div > .chartTitle">
<ng-template ngFor [ngForOf]="activeSubCategory.charts" let-chart let-i="index">
<div *ngIf="chart.isActive && chart.isPublic && chartsActiveType.get(i)"
[class.uk-width-1-3@m]="chart.width === 'small'"
[class.uk-width-1-2@m]="chart.width === 'medium'"
[class.uk-width-1-1]="chart.width === 'large'">
<div class="indicatorBox">
<h4 class="uk-margin-bottom uk-margin-top chartTitle uk-flex uk-flex-bottom ">
<div>{{chart.name + " "}}</div>
</h4>
<div class="md-card" [attr.uk-tooltip]="chart.description">
<div class="md-card-content uk-text-center">
<div *ngIf="chart.indicatorPaths.length > 1" class="uk-button-group">
<button *ngFor="let indicatorPath of chart.indicatorPaths;"
class="uk-button"
(click)="setActiveChart(i, indicatorPath.type)"
[class.uk-button-secondary]="chartsActiveType.get(i).url === indicatorPath.url">
{{indicatorPath.type}}
</button>
</div>
<iframe *ngIf="chartsActiveType.get(i).source !== 'image'"
[src]="chartsActiveType.get(i).safeResourceUrl"
class="uk-width-1-1 uk-height-medium"></iframe>
<!-- {{chartsActiveType.get(i).safeResourceUrl}}-->
<img *ngIf="chartsActiveType.get(i).source === 'image'"
[src]="chartsActiveType.get(i).safeResourceUrl"
class="uk-width-1-1 uk-height-medium">
</div>
</div>
</div>
</div>
</ng-template>
</div>
</div>
</div>
</div>
<a *ngIf="stakeholder" id="style_switcher" class="" routerLinkActive="active"
[routerLink]="['/admin', this.stakeholder.alias]">
<div id="style_switcher_toggle"><i class="material-icons">settings</i></div>
</a>
</div> </div>

View File

@ -85,47 +85,47 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
this.status = this.errorCodes.LOADING; this.status = this.errorCodes.LOADING;
this.numberResults = new Map<number, number>(); this.numberResults = new Map<number, number>();
this.chartsActiveType = new Map<number, IndicatorPath>(); this.chartsActiveType = new Map<number, IndicatorPath>();
// this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
let stakeholder: Stakeholder = null; /*let stakeholder: Stakeholder = null;
if (params['stakeholder'] == "fwf") { if (params['stakeholder'] == "fwf") {
stakeholder = new Stakeholder(null, "funder", "fwf_________::FWF", "Austrian Science Fund (FWF)", "FWF", stakeholder = new Stakeholder(null, "funder", "fwf_________::FWF", "Austrian Science Fund (FWF)", "FWF",
false, "fwf", true, true, null); false, "fwf", true, true, null);
stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics);
stakeholder.logoUrl = "./assets/fwf.png"; stakeholder.logoUrl = "./assets/fwf.png";
} else if (params['stakeholder'] == "arc") { } else if (params['stakeholder'] == "arc") {
stakeholder = new Stakeholder(null, "funder", "arc_________::ARC", stakeholder = new Stakeholder(null, "funder", "arc_________::ARC",
"Australian Research Council (ARC)", "ARC", "Australian Research Council (ARC)", "ARC",
false, null, true, true, null); false, null, true, true, null);
stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics);
stakeholder.logoUrl = "./assets/arc1.gif"; stakeholder.logoUrl = "./assets/arc1.gif";
} else { } else {
stakeholder = new Stakeholder(null, "funder", "ec__________::EC", stakeholder = new Stakeholder(null, "funder", "ec__________::EC",
"European Commission", "EC", "European Commission", "EC",
false, "ec", true, true, null); false, "ec", true, true, null);
stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics);
stakeholder.logoUrl = "./assets/ec.png"; stakeholder.logoUrl = "./assets/ec.png";
} }*/
if (stakeholder) { if (stakeholder) {
this.stakeholder = stakeholder; this.stakeholder = stakeholder;
this.seoService.createLinkForCanonicalURL(url, false); this.seoService.createLinkForCanonicalURL(url, false);
this._meta.updateTag({content: url}, "property='og:url'"); this._meta.updateTag({content: url}, "property='og:url'");
var description = "Monitor Dashboard | " + this.stakeholder.index_name; var description = "Monitor Dashboard | " + this.stakeholder.index_name;
var title = "Monitor Dashboard | " + this.stakeholder.index_shortName; var title = "Monitor Dashboard | " + this.stakeholder.index_shortName;
this._meta.updateTag({content: description}, "name='description'"); this._meta.updateTag({content: description}, "name='description'");
this._meta.updateTag({content: description}, "property='og:description'"); this._meta.updateTag({content: description}, "property='og:description'");
this._meta.updateTag({content: title}, "property='og:title'"); this._meta.updateTag({content: title}, "property='og:title'");
this._title.setTitle(title); this._title.setTitle(title);
if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) { if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
this.piwiksub = this._piwikService.trackView(this.properties, title, this.properties.piwikSiteId).subscribe(); this.piwiksub = this._piwikService.trackView(this.properties, title, this.properties.piwikSiteId).subscribe();
}
//this.getDivContents();
this.getPageContents();
this.status = this.errorCodes.DONE;
this.setView(params);
} }
//this.getDivContents(); }, error => {
this.getPageContents(); this.navigateToError();
this.status = this.errorCodes.DONE; })
this.setView(params);
}
// }, error => {
// this.navigateToError();
// })
} else { } else {
this.setView(params); this.setView(params);
} }
@ -172,25 +172,27 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
} }
private setView(params: Params) { private setView(params: Params) {
if (params && params['topic']) { if (params['topic']) {
this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && topic.isPublic && topic.isActive); this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && topic.isPublic && topic.isActive);
if (this.activeTopic) { if (this.activeTopic) {
if (params['category']) { if (params['category']) {
this.activeCategory = this.activeTopic.categories.find(category => this.activeCategory = this.activeTopic.categories.find(category =>
(category.alias === params['category']) && category.isPublic && category.isActive); (category.alias === params['category']) && category.isPublic && category.isActive);
if(!this.activeCategory) {
this.navigateToError();
return;
}
} else { } else {
this.activeCategory = this.activeTopic.categories.find(category => category.isPublic && category.isActive); this.activeCategory = this.activeTopic.categories.find(category => category.isPublic && category.isActive);
if (this.activeCategory) { if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
subCategory.isPublic && subCategory.isActive); subCategory.isPublic && subCategory.isActive);
this.setSideBar();
if (this.activeSubCategory) { if (this.activeSubCategory) {
this.setSideBar();
this.setIndicators(); this.setIndicators();
} else {
this.navigateToError();
} }
} else { } else {
this.navigateToError(); this.setSideBar();
} }
return; return;
} }
@ -198,6 +200,10 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
if (params['subCategory']) { if (params['subCategory']) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
(subCategory.alias === params['subCategory'] && subCategory.isPublic && subCategory.isActive)); (subCategory.alias === params['subCategory'] && subCategory.isPublic && subCategory.isActive));
if(!this.activeSubCategory) {
this.navigateToError();
return;
}
} else { } else {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
subCategory.isPublic && subCategory.isActive); subCategory.isPublic && subCategory.isActive);
@ -209,9 +215,13 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
this.navigateToError(); this.navigateToError();
} }
return; return;
} else {
this.activeSubCategory = null;
} }
} else {
this.navigateToError();
return;
} }
this.navigateToError();
} else { } else {
this.activeTopic = this.stakeholder.topics.find(topic => topic.isPublic && topic.isActive); this.activeTopic = this.stakeholder.topics.find(topic => topic.isPublic && topic.isActive);
if (this.activeTopic) { if (this.activeTopic) {
@ -254,6 +264,9 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
subItems, null, open)); subItems, null, open));
} }
}); });
if(items.length === 0) {
items.push(new Item('noCategories', 'No categories available yet', null, [], null, false));
}
this.sideBar = new Sidebar(items, null); this.sideBar = new Sidebar(items, null);
} }

View File

@ -12,177 +12,189 @@ import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {Subscriber} from "rxjs"; import {Subscriber} from "rxjs";
import {FormBuilder, FormGroup, Validators} from "@angular/forms"; import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {LayoutService} from "../library/sharedComponents/sidebar/layout.service"; import {LayoutService} from "../library/sharedComponents/sidebar/layout.service";
import {IndicatorUtils} from "../utils/indicator-utils"; import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
declare var UIkit; declare var UIkit;
@Component({ @Component({
selector: 'stakeholder', selector: 'stakeholder',
templateUrl: './stakeholder.component.html', templateUrl: './stakeholder.component.html',
}) })
export class StakeholderComponent implements OnInit, OnDestroy { export class StakeholderComponent implements OnInit, OnDestroy {
public subscriptions: any[] = []; public subscriptions: any[] = [];
public loading: boolean = true; public loading: boolean = true;
public errorCodes: ErrorCodes; public errorCodes: ErrorCodes;
public stakeholder: Stakeholder; public stakeholder: Stakeholder;
public analysisOpen: boolean = true; public analysisOpen: boolean = true;
private errorMessages: ErrorMessagesComponent; private errorMessages: ErrorMessagesComponent;
public topicFb: FormGroup; public topicFb: FormGroup;
public indicatorUtils: IndicatorUtils = new IndicatorUtils(); public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public element: any; public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public index: number; public element: any;
properties: EnvProperties; public index: number;
properties: EnvProperties;
@ViewChild('deleteTopicModal') deleteTopicModal: AlertModal; @ViewChild('deleteTopicModal') deleteTopicModal: AlertModal;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private title: Title, private title: Title,
private layoutService: LayoutService, private layoutService: LayoutService,
private fb: FormBuilder, private fb: FormBuilder,
private stakeholderService: StakeholderService) { private stakeholderService: StakeholderService) {
this.errorCodes = new ErrorCodes(); this.errorCodes = new ErrorCodes();
this.errorMessages = new ErrorMessagesComponent(); this.errorMessages = new ErrorMessagesComponent();
} }
public ngOnInit() { public ngOnInit() {
this.route.data this.route.data
.subscribe((data: { envSpecific: EnvProperties }) => { .subscribe((data: { envSpecific: EnvProperties }) => {
this.properties = data.envSpecific; this.properties = data.envSpecific;
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) { if (stakeholder) {
this.stakeholder = HelperFunctions.copy(stakeholder); this.stakeholder = HelperFunctions.copy(stakeholder);
this.topicFb = null; this.topicFb = null;
this.title.setTitle(stakeholder.index_name); this.title.setTitle(stakeholder.index_name);
}
}));
});
}
public ngOnDestroy() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
}
public show(element) {
UIkit.drop(element).show();
}
public hide(element) {
UIkit.drop(element).hide();
}
get open(): boolean {
return this.layoutService.open;
}
public toggleOpen(event = null) {
if (!event) {
this.layoutService.setOpen(!this.open);
} else if (event && event['value'] === true) {
this.layoutService.setOpen(false);
}
}
private buildTopic(topic: Topic) {
let topics = this.stakeholder.topics.filter(element => element._id !== topic._id);
this.topicFb = this.fb.group({
_id: this.fb.control(topic._id),
name: this.fb.control(topic.name, Validators.required),
description: this.fb.control(topic.description),
alias: this.fb.control(topic.alias, [
Validators.required,
this.stakeholderUtils.aliasValidator(topics)
]
),
isActive: this.fb.control(topic.isActive),
isPublic: this.fb.control(topic.isPublic),
isDefault: this.fb.control(topic.isDefault),
categories: this.fb.control(topic.categories)
});
this.subscriptions.push(this.topicFb.get('name').valueChanges.subscribe(value => {
let i = 1;
value = this.stakeholderUtils.generateAlias(value);
this.topicFb.controls['alias'].setValue(value);
while (this.topicFb.get('alias').invalid) {
this.topicFb.controls['alias'].setValue(value + i);
i++;
} }
})); }));
});
}
public ngOnDestroy() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
}
public show(element) {
UIkit.drop(element).show();
}
public hide(element) {
UIkit.drop(element).hide();
}
get open(): boolean {
return this.layoutService.open;
}
public toggleOpen(event = null) {
if (!event) {
this.layoutService.setOpen(!this.open);
} else if (event && event['value'] === true) {
this.layoutService.setOpen(false);
} }
}
private buildTopic(topic: Topic) { public saveTopicOpen(element, index = -1) {
this.topicFb = this.fb.group({ if (element.className.indexOf('uk-open') !== -1) {
_id: this.fb.control(topic._id), this.hide(element);
name: this.fb.control(topic.name, Validators.required), } else {
description: this.fb.control(topic.description), if (index === -1) {
alias: this.fb.control(topic.alias), this.buildTopic(new Topic(null, null, null, true, true, false));
isActive: this.fb.control(topic.isActive), } else {
isPublic: this.fb.control(topic.isPublic), this.buildTopic(this.stakeholder.topics[index]);
isDefault: this.fb.control(topic.isDefault), }
categories: this.fb.control(topic.categories) this.show(element);
}); }
}
public saveTopicOpen(element, index = -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if (index === -1) {
this.buildTopic(new Topic(null, null, null, true, true, false));
} else {
this.buildTopic(this.stakeholder.topics[index]);
}
this.show(element);
} }
}
public saveTopic(element, index = -1) { public saveTopic(element, index = -1) {
if (!this.topicFb.invalid) { if (!this.topicFb.invalid) {
if (!this.topicFb.value.alias) { if (index === -1) {
this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim(); this.save('Topic has been successfully created', element);
} } else {
if (index === -1) { this.save('Topic has been successfully saved', element, index);
this.save('Topic has been successfully created', element); }
} else { }
this.save('Topic has been successfully saved', element, index);
}
} }
}
public deleteTopicOpen(name: string, element, index: number) { public deleteTopicOpen(name: string, element, index: number) {
this.element = element; this.element = element;
this.index = index; this.index = index;
this.deleteTopicModal.alertTitle = 'Delete ' + name; this.deleteTopicModal.alertTitle = 'Delete ' + name;
this.deleteTopicModal.cancelButtonText = 'No'; this.deleteTopicModal.cancelButtonText = 'No';
this.deleteTopicModal.okButtonText = 'Yes'; this.deleteTopicModal.okButtonText = 'Yes';
this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?'; this.deleteTopicModal.message = 'This topic will permanently be deleted. Are you sure you want to proceed?';
this.deleteTopicModal.open(); this.deleteTopicModal.open();
} }
private save(message: string, element, index: number = -1) { private save(message: string, element, index: number = -1) {
let path = [this.stakeholder._id]; let path = [this.stakeholder._id];
this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.topicFb.value, path).subscribe(topic => { this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.topicFb.value, path).subscribe(topic => {
if (index === -1) { if (index === -1) {
this.stakeholder.topics.push(topic); this.stakeholder.topics.push(topic);
} else { } else {
this.stakeholder.topics[index] = topic; this.stakeholder.topics[index] = topic;
} }
this.stakeholderService.setStakeholder(this.stakeholder); this.stakeholderService.setStakeholder(this.stakeholder);
UIkit.notification(message, { UIkit.notification(message, {
status: 'success', status: 'success',
timeout: 3000000, timeout: 3000,
pos: 'top-left' pos: 'top-left'
}); });
this.hide(element); this.hide(element);
}, error => { }, error => {
UIkit.notification(error.error.message, { UIkit.notification(error.error.message, {
status: 'danger', status: 'danger',
timeout: 3000, timeout: 3000,
pos: 'top-left' pos: 'top-left'
}); });
this.hide(element); this.hide(element);
}); });
} }
deleteTopic() { deleteTopic() {
let path = [ let path = [
this.stakeholder._id, this.stakeholder._id,
this.stakeholder.topics[this.index]._id this.stakeholder.topics[this.index]._id
]; ];
this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => { this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => {
this.stakeholder.topics.splice(this.index, 1); this.stakeholder.topics.splice(this.index, 1);
this.stakeholderService.setStakeholder(this.stakeholder); this.stakeholderService.setStakeholder(this.stakeholder);
UIkit.notification('Topic has been successfully deleted', { UIkit.notification('Topic has been successfully deleted', {
status: 'success', status: 'success',
timeout: 3000, timeout: 3000,
pos: 'top-left' pos: 'top-left'
}); });
this.hide(this.element); this.hide(this.element);
}, error => { }, error => {
UIkit.notification(error.error.message, { UIkit.notification(error.error.message, {
status: 'danger', status: 'danger',
timeout: 3000, timeout: 3000,
pos: 'top-left' pos: 'top-left'
}); });
this.hide(this.element); this.hide(this.element);
}); });
} }
} }

View File

@ -76,7 +76,7 @@
<i class="md-icon material-icons">more_vert</i> <i class="md-icon material-icons">more_vert</i>
<div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal"> <div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li><a (click)="editIndicatorOpen(indicator._id)">Edit</a></li> <li><a (click)="editChartIndicatorOpen(indicator._id)">Edit</a></li>
<li><a (click)="deleteIndicatorOpen(indicator._id, 'number')">Delete</a></li> <li><a (click)="deleteIndicatorOpen(indicator._id, 'number')">Delete</a></li>
</ul> </ul>
</div> </div>
@ -142,7 +142,7 @@
<i class="md-icon material-icons">more_vert</i> <i class="md-icon material-icons">more_vert</i>
<div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal"> <div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal">
<ul class="uk-nav uk-dropdown-nav"> <ul class="uk-nav uk-dropdown-nav">
<li><a (click)="editIndicatorOpen(indicator._id)">Edit</a></li> <li><a (click)="editChartIndicatorOpen(indicator._id)">Edit</a></li>
<li><a (click)="deleteIndicatorOpen(indicator._id)">Delete</a></li> <li><a (click)="deleteIndicatorOpen(indicator._id)">Delete</a></li>
</ul> </ul>
</div> </div>

View File

@ -292,7 +292,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.editIndicatorModal.open(); this.editIndicatorModal.open();
} }
public createIndicator() { public createChartIndicator() {
this.indicator = new Indicator( this.indicator = new Indicator(
this.indicatorFb.value.name, this.indicatorFb.value.name,
this.indicatorFb.value.description, this.indicatorFb.value.description,
@ -306,10 +306,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.indicator.indicatorPaths.push( this.indicator.indicatorPaths.push(
this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(url), url)); this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(url), url));
}); });
this.editIndicatorOpen(); this.editChartIndicatorOpen();
} }
public editIndicatorOpen(id = null) { public editChartIndicatorOpen(id = null) {
this.index = (id)?this.charts.findIndex(value => value._id === id):-1; this.index = (id)?this.charts.findIndex(value => value._id === id):-1;
if (this.index !== -1) { if (this.index !== -1) {
this.indicator = HelperFunctions.copy(this.charts[this.index]); this.indicator = HelperFunctions.copy(this.charts[this.index]);
@ -341,12 +341,12 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
}); });
this.indicatorFb = this.fb.group({ this.indicatorFb = this.fb.group({
id: this.fb.control(this.indicator._id), id: this.fb.control(this.indicator._id),
name: this.fb.control(this.indicator.name, Validators.required), name: this.fb.control(this.indicator.name/*, Validators.required*/),
description: this.fb.control(this.indicator.description), description: this.fb.control(this.indicator.description),
isPublic: this.fb.control(this.indicator.isPublic), isPublic: this.fb.control(this.indicator.isPublic),
isActive: this.fb.control(this.indicator.isActive), isActive: this.fb.control(this.indicator.isActive),
indicatorPaths: indicatorPaths, indicatorPaths: indicatorPaths,
width: this.fb.control(this.indicator.width, Validators.required), width: this.fb.control(this.indicator.width),
}); });
if(this.index === -1) { if(this.index === -1) {
this.editIndicatorModal.okButtonText = 'Save'; this.editIndicatorModal.okButtonText = 'Save';
@ -365,7 +365,9 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
saveIndicator() { saveIndicator() {
if(this.indicator) { if(this.indicator) {
this.indicator = this.indicatorUtils.generateIndicatorByForm(this.indicatorFb.value, this.indicator.indicatorPaths); if(this.indicator.type === 'chart') {
this.indicator = this.indicatorUtils.generateIndicatorByForm(this.indicatorFb.value, this.indicator.indicatorPaths);
}
let path = [ let path = [
this.stakeholder._id, this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex]._id,
@ -385,7 +387,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.indicatorFb = null; this.indicatorFb = null;
}); });
} else { } else {
this.createIndicator(); this.createChartIndicator();
} }
} }

View File

@ -6,368 +6,402 @@ import {Category, Stakeholder, SubCategory, Topic} from "../utils/entities/stake
import {StakeholderService} from "../services/stakeholder.service"; import {StakeholderService} from "../services/stakeholder.service";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {AlertModal} from "../openaireLibrary/utils/modal/alert"; import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {Subscriber} from "rxjs"; import {Subscriber, Subscription} from "rxjs";
import {FormBuilder, FormGroup, Validators} from "@angular/forms"; import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {IndicatorUtils} from "../utils/indicator-utils"; import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
declare var UIkit; declare var UIkit;
@Component({ @Component({
selector: 'topic', selector: 'topic',
templateUrl: './topic.component.html', templateUrl: './topic.component.html',
}) })
export class TopicComponent implements OnInit, OnDestroy { export class TopicComponent implements OnInit, OnDestroy {
public subscriptions: any[] = []; public subscriptions: any[] = [];
public properties: EnvProperties; public properties: EnvProperties;
public indicatorUtils: IndicatorUtils = new IndicatorUtils(); public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public loading: boolean = true; public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public stakeholder: Stakeholder; public loading: boolean = true;
/** public stakeholder: Stakeholder;
* Current topic /**
**/ * Current topic
public topicIndex: number = 0; **/
public topicFb: FormGroup; public topicIndex: number = 0;
public topicFb: FormGroup;
/** /**
* categoryIndex: Current category to be edited, selectedCategoryIndex: selected on menu(opened) * categoryIndex: Current category to be edited, selectedCategoryIndex: selected on menu(opened)
*/ */
public categoryIndex: number = 0; public categoryIndex: number = 0;
public selectedCategoryIndex: number = 0; public selectedCategoryIndex: number = 0;
public categoryFb: FormGroup; public categoryFb: FormGroup;
/** /**
* Current Subcategory to be edited * Current Subcategory to be edited
*/ */
public subCategoryIndex: number = 0; public subCategoryIndex: number = 0;
public subcategoryFb: FormGroup; public subcategoryFb: FormGroup;
/** /**
* Current drop element and index of topic, category or subcategory to be deleted. * Current drop element and index of topic, category or subcategory to be deleted.
*/ */
public element: any; public element: any;
public index: number; public index: number;
/** /**
* Check form validity * Check form validity
*/ */
public toggle: boolean = false; public toggle: boolean = false;
@ViewChild('deleteTopicModal') deleteTopicModal: AlertModal; @ViewChild('deleteTopicModal') deleteTopicModal: AlertModal;
@ViewChild('deleteCategoryModal') deleteCategoryModal: AlertModal; @ViewChild('deleteCategoryModal') deleteCategoryModal: AlertModal;
@ViewChild('deleteSubcategoryModal') deleteSubcategoryModal: AlertModal; @ViewChild('deleteSubcategoryModal') deleteSubcategoryModal: AlertModal;
constructor( constructor(
private route: ActivatedRoute, private route: ActivatedRoute,
private router: Router, private router: Router,
private title: Title, private title: Title,
private fb: FormBuilder, private fb: FormBuilder,
private stakeholderService: StakeholderService) { private stakeholderService: StakeholderService) {
} }
public ngOnInit() { public ngOnInit() {
this.route.data this.route.data
.subscribe((data: { envSpecific: EnvProperties }) => { .subscribe((data: { envSpecific: EnvProperties }) => {
this.properties = data.envSpecific; this.properties = data.envSpecific;
this.route.params.subscribe( params => { let subscription: Subscription;
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { this.subscriptions.push(this.route.params.subscribe(params => {
if (stakeholder) { if(subscription) {
this.stakeholder = HelperFunctions.copy(stakeholder); subscription.unsubscribe();
this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']); }
if(this.topicIndex === -1) { subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.navigateToError(); if (stakeholder) {
} else { this.stakeholder = HelperFunctions.copy(stakeholder);
this.title.setTitle(stakeholder.index_shortName + ' | ' + this.stakeholder.topics[this.topicIndex].name); this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
this.toggle = true; if (this.topicIndex === -1) {
} this.navigateToError();
} else {
this.title.setTitle(stakeholder.index_shortName + ' | ' + this.stakeholder.topics[this.topicIndex].name);
this.toggle = true;
}
}
});
}));
});
}
public ngOnDestroy() {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
} }
}));
}); });
});
}
public ngOnDestroy() {
this.subscriptions.forEach( value => {
if(value instanceof Subscriber) {
value.unsubscribe();
}
});
}
public hide(element) {
UIkit.drop(element).hide();
}
public show(element) {
UIkit.drop(element).show();
}
private buildTopic(topic: Topic) {
this.topicFb = this.fb.group({
_id: this.fb.control(topic._id),
name: this.fb.control(topic.name, Validators.required),
description: this.fb.control(topic.description),
alias: this.fb.control(topic.alias),
isActive: this.fb.control(topic.isActive),
isPublic: this.fb.control(topic.isPublic),
isDefault: this.fb.control(topic.isDefault),
categories: this.fb.control(topic.categories)
});
}
public editTopicOpen(element) {
if(element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
this.buildTopic(this.stakeholder.topics[this.topicIndex]);
this.show(element);
} }
}
public saveTopic(element) { public hide(element) {
if(!this.topicFb.invalid) { UIkit.drop(element).hide();
if(!this.topicFb.value.alias) {
this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
}
let path = [this.stakeholder._id];
let callback = (topic: Topic): void => {
this.stakeholder.topics[this.topicIndex] = topic;
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.save('Topic has been successfully saved', element, path, this.topicFb.value, callback,true);
} }
}
public deleteTopicOpen(name: string, element) { public show(element) {
this.deleteOpen(name,'topic', this.deleteTopicModal, element, this.topicIndex); UIkit.drop(element).show();
}
public deleteTopic() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id
];
let callback = (): void => {
this.stakeholder.topics.splice(this.topicIndex, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Topic has been successfully be deleted', path, callback, true);
}
public toggleCategory(index: number) {
if(this.selectedCategoryIndex !== index) {
this.selectedCategoryIndex = index;
this.toggle = true;
} else {
this.toggle = !this.toggle;
} }
}
private buildCategory(category: Category) { private buildTopic(topic: Topic) {
this.categoryFb = this.fb.group({ let topics = this.stakeholder.topics.filter(element => element._id !== topic._id);
_id: this.fb.control(category._id), this.topicFb = this.fb.group({
name: this.fb.control(category.name, Validators.required), _id: this.fb.control(topic._id),
description: this.fb.control(category.description), name: this.fb.control(topic.name, Validators.required),
alias: this.fb.control(category.alias), description: this.fb.control(topic.description),
isActive: this.fb.control(category.isActive), alias: this.fb.control(topic.alias, [
isPublic: this.fb.control(category.isPublic), Validators.required,
isDefault: this.fb.control(category.isDefault), this.stakeholderUtils.aliasValidator(topics)
subCategories: this.fb.control(category.subCategories) ]
}); ),
} isActive: this.fb.control(topic.isActive),
isPublic: this.fb.control(topic.isPublic),
public editCategoryOpen(element, index:number = -1) { isDefault: this.fb.control(topic.isDefault),
if(element.className.indexOf('uk-open') !== -1) { categories: this.fb.control(topic.categories)
this.hide(element);
} else {
if(index === -1) {
this.buildCategory(new Category(null, null, null, true, true));
} else {
this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]);
}
this.show(element);
}
}
public saveCategory(element, index = -1) {
if(!this.categoryFb.invalid) {
if(!this.categoryFb.value.alias) {
this.categoryFb.value.alias = this.categoryFb.value.name.toLowerCase();
}
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
let callback = (category: Category): void => {
if(index === -1) {
this.stakeholder.topics[this.topicIndex].categories.push(category);
} else {
this.stakeholder.topics[this.topicIndex].categories[index] = HelperFunctions.copy(category);
}
this.stakeholderService.setStakeholder(this.stakeholder);
};
if(index === -1) {
this.save('Category has been successfully created', element, path, this.categoryFb.value, callback);
} else {
this.save('Category has been successfully saved', element, path, this.categoryFb.value, callback);
}
}
}
public deleteCategoryOpen(name: string, element, index) {
this.deleteOpen(name,'category', this.deleteCategoryModal, element, index);
}
public deleteCategory() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
];
let callback = (): void => {
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Category has been successfully be deleted', path, callback);
}
private buildSubcategory(subCategory: SubCategory) {
this.subcategoryFb = this.fb.group({
_id: this.fb.control(subCategory._id),
name: this.fb.control(subCategory.name, Validators.required),
description: this.fb.control(subCategory.description),
alias: this.fb.control(subCategory.alias),
isActive: this.fb.control(subCategory.isActive),
isPublic: this.fb.control(subCategory.isPublic),
isDefault: this.fb.control(subCategory.isDefault),
charts: this.fb.control(subCategory.charts),
numbers: this.fb.control(subCategory.numbers)
});
}
public editSubCategoryOpen(element, index:number = -1) {
if(element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if(index === -1) {
this.buildSubcategory(new SubCategory(null, null, null, true, true));
} else {
this.buildSubcategory(this.stakeholder.topics[this.topicIndex].
categories[this.selectedCategoryIndex].subCategories[index]);
}
this.show(element);
}
}
public saveSubCategory(element, index = -1) {
if(!this.subcategoryFb.invalid) {
if(!this.subcategoryFb.value.alias) {
this.subcategoryFb.value.alias = this.subcategoryFb.value.name.toLowerCase();
}
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
];
let callback = (subCategory: SubCategory): void => {
if(index === -1) {
this.stakeholder.topics[this.topicIndex].
categories[this.selectedCategoryIndex].subCategories.push(subCategory);
} else {
this.stakeholder.topics[this.topicIndex].
categories[this.selectedCategoryIndex].subCategories[index] = subCategory;
}
this.stakeholderService.setStakeholder(this.stakeholder);
};
if(index === -1) {
this.save('Subcategory has been successfully created', element, path, this.subcategoryFb.value, callback);
} else {
this.save('Subcategory has been successfully saved', element, path, this.subcategoryFb.value, callback);
}
this.hide(element);
}
}
public deleteSubcategoryOpen(name: string, element, index) {
this.deleteOpen(name,'subcategory', this.deleteSubcategoryModal, element, index);
}
public deleteSubcategory() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index]._id
];
let callback = (): void => {
this.stakeholder.topics[this.topicIndex].
categories[this.selectedCategoryIndex].subCategories.splice(this.index, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Subcategory has been successfully be deleted', path, callback);
}
private navigateToError() {
this.router.navigate(['/error'], {queryParams: {'page': this.router.url}});
}
private deleteOpen(name: string, type: string, modal: AlertModal, element, index) {
this.element = element;
this.index = index;
modal.alertTitle = 'Delete ' + name;
modal.cancelButtonText = 'No';
modal.okButtonText = 'Yes';
modal.message = 'This ' + type + ' will permanently be deleted. Are you sure you want to proceed?';
modal.open();
}
private save(message: string, element, path: string[], saveElement: any, callback: Function, redirect = false) {
this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
callback(saveElement);
UIkit.notification(message, {
status: 'success',
timeout: 3000,
pos: 'top-left'
});
if(redirect) {
this.router.navigate(['../' + saveElement.alias], {
relativeTo: this.route
}); });
} this.subscriptions.push(this.topicFb.get('name').valueChanges.subscribe(value => {
this.hide(element); let i = 1;
}, error => { value = this.stakeholderUtils.generateAlias(value);
UIkit.notification(error.error.message, { this.topicFb.controls['alias'].setValue(value);
status: 'danger', while (this.topicFb.get('alias').invalid) {
timeout: 3000, this.topicFb.controls['alias'].setValue(value + i);
pos: 'top-left' i++;
}); }
this.hide(element); }));
}); }
}
private delete(message: string, path: string[], callback: Function, redirect = false) { public editTopicOpen(element) {
this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => { if (element.className.indexOf('uk-open') !== -1) {
callback(); this.hide(element);
UIkit.notification(message, { } else {
status: 'success', this.buildTopic(this.stakeholder.topics[this.topicIndex]);
timeout: 3000, this.show(element);
pos: 'top-left' }
}); }
if(redirect) {
this.back();
}
this.hide(this.element);
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 3000,
pos: 'top-left'
});
this.hide(this.element);
});
}
back() { public saveTopic(element) {
this.router.navigate(['../'], { if (!this.topicFb.invalid) {
relativeTo: this.route let path = [this.stakeholder._id];
}); let callback = (topic: Topic): void => {
} this.stakeholder.topics[this.topicIndex] = topic;
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.save('Topic has been successfully saved', element, path, this.topicFb.value, callback, true);
}
}
chooseSubcategory(categoryIndex: number, subcategoryIndex: number) { public deleteTopicOpen(name: string, element) {
this.categoryIndex = categoryIndex; this.deleteOpen(name, 'topic', this.deleteTopicModal, element, this.topicIndex);
this.subCategoryIndex = subcategoryIndex; }
}
public deleteTopic() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id
];
let callback = (): void => {
this.stakeholder.topics.splice(this.topicIndex, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Topic has been successfully be deleted', path, callback, true);
}
public toggleCategory(index: number) {
if (this.selectedCategoryIndex !== index) {
this.selectedCategoryIndex = index;
this.toggle = true;
} else {
this.toggle = !this.toggle;
}
}
private buildCategory(category: Category) {
let categories = this.stakeholder.topics[this.topicIndex].categories.filter(element => element._id !== category._id);
this.categoryFb = this.fb.group({
_id: this.fb.control(category._id),
name: this.fb.control(category.name, Validators.required),
description: this.fb.control(category.description),
alias: this.fb.control(category.alias, [
Validators.required,
this.stakeholderUtils.aliasValidator(categories)
]
),
isActive: this.fb.control(category.isActive),
isPublic: this.fb.control(category.isPublic),
isDefault: this.fb.control(category.isDefault),
subCategories: this.fb.control(category.subCategories)
});
this.subscriptions.push(this.categoryFb.get('name').valueChanges.subscribe(value => {
let i = 1;
value = this.stakeholderUtils.generateAlias(value);
this.categoryFb.controls['alias'].setValue(value);
while (this.categoryFb.get('alias').invalid) {
this.categoryFb.controls['alias'].setValue(value + i);
i++;
}
}));
}
public editCategoryOpen(element, index: number = -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if (index === -1) {
this.buildCategory(new Category(null, null, null, true, true));
} else {
this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]);
}
this.show(element);
}
}
public saveCategory(element, index = -1) {
if (!this.categoryFb.invalid) {
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
let callback = (category: Category): void => {
if (index === -1) {
this.stakeholder.topics[this.topicIndex].categories.push(category);
} else {
this.stakeholder.topics[this.topicIndex].categories[index] = HelperFunctions.copy(category);
}
this.stakeholderService.setStakeholder(this.stakeholder);
};
if (index === -1) {
this.save('Category has been successfully created', element, path, this.categoryFb.value, callback);
} else {
this.save('Category has been successfully saved', element, path, this.categoryFb.value, callback);
}
}
}
public deleteCategoryOpen(name: string, element, index) {
this.deleteOpen(name, 'category', this.deleteCategoryModal, element, index);
}
public deleteCategory() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
];
let callback = (): void => {
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Category has been successfully be deleted', path, callback);
}
private buildSubcategory(subCategory: SubCategory) {
let subCategories = this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.filter(element => element._id !== subCategory._id);
this.subcategoryFb = this.fb.group({
_id: this.fb.control(subCategory._id),
name: this.fb.control(subCategory.name, Validators.required),
description: this.fb.control(subCategory.description),
alias: this.fb.control(subCategory.alias, [
Validators.required,
this.stakeholderUtils.aliasValidator(subCategories)
]
),
isActive: this.fb.control(subCategory.isActive),
isPublic: this.fb.control(subCategory.isPublic),
isDefault: this.fb.control(subCategory.isDefault),
charts: this.fb.control(subCategory.charts),
numbers: this.fb.control(subCategory.numbers)
});
this.subscriptions.push(this.subcategoryFb.get('name').valueChanges.subscribe(value => {
let i = 1;
value = this.stakeholderUtils.generateAlias(value);
this.subcategoryFb.controls['alias'].setValue(value);
while (this.subcategoryFb.get('alias').invalid) {
this.subcategoryFb.controls['alias'].setValue(value + i);
i++;
}
}));
}
public editSubCategoryOpen(element, index: number = -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if (index === -1) {
this.buildSubcategory(new SubCategory(null, null, null, true, true));
} else {
this.buildSubcategory(this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[index]);
}
this.show(element);
}
}
public saveSubCategory(element, index = -1) {
if (!this.subcategoryFb.invalid) {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
];
let callback = (subCategory: SubCategory): void => {
if (index === -1) {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.push(subCategory);
} else {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[index] = subCategory;
}
this.stakeholderService.setStakeholder(this.stakeholder);
};
if (index === -1) {
this.save('Subcategory has been successfully created', element, path, this.subcategoryFb.value, callback);
} else {
this.save('Subcategory has been successfully saved', element, path, this.subcategoryFb.value, callback);
}
this.hide(element);
}
}
public deleteSubcategoryOpen(name: string, element, index) {
this.deleteOpen(name, 'subcategory', this.deleteSubcategoryModal, element, index);
}
public deleteSubcategory() {
let path: string[] = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index]._id
];
let callback = (): void => {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.splice(this.index, 1);
this.stakeholderService.setStakeholder(this.stakeholder);
};
this.delete('Subcategory has been successfully be deleted', path, callback);
}
private navigateToError() {
this.router.navigate(['/error'], {queryParams: {'page': this.router.url}});
}
private deleteOpen(name: string, type: string, modal: AlertModal, element, index) {
this.element = element;
this.index = index;
modal.alertTitle = 'Delete ' + name;
modal.cancelButtonText = 'No';
modal.okButtonText = 'Yes';
modal.message = 'This ' + type + ' will permanently be deleted. Are you sure you want to proceed?';
modal.open();
}
private save(message: string, element, path: string[], saveElement: any, callback: Function, redirect = false) {
this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
callback(saveElement);
UIkit.notification(message, {
status: 'success',
timeout: 3000,
pos: 'top-left'
});
if (redirect) {
this.router.navigate(['../' + saveElement.alias], {
relativeTo: this.route
});
}
this.hide(element);
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 3000,
pos: 'top-left'
});
this.hide(element);
});
}
private delete(message: string, path: string[], callback: Function, redirect = false) {
this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => {
callback();
UIkit.notification(message, {
status: 'success',
timeout: 3000,
pos: 'top-left'
});
if (redirect) {
this.back();
}
this.hide(this.element);
}, error => {
UIkit.notification(error.error.message, {
status: 'danger',
timeout: 3000,
pos: 'top-left'
});
this.hide(this.element);
});
}
back() {
this.router.navigate(['../'], {
relativeTo: this.route
});
}
chooseSubcategory(categoryIndex: number, subcategoryIndex: number) {
this.categoryIndex = categoryIndex;
this.subCategoryIndex = subcategoryIndex;
}
} }

View File

@ -1,5 +1,5 @@
import {ChartHelper, Indicator, IndicatorPath, Stakeholder, SubCategory, Topic} from "./entities/stakeholder"; import {ChartHelper, Indicator, IndicatorPath, Stakeholder, SubCategory, Topic} from "./entities/stakeholder";
import {Validators} from "@angular/forms"; import {AbstractControl, ValidatorFn, Validators} from "@angular/forms";
export interface Option { export interface Option {
icon?: string, icon?: string,
@ -84,6 +84,27 @@ export class StakeholderUtils {
} }
return funder; return funder;
} }
aliasValidator(elements: any[]): ValidatorFn {
return (control: AbstractControl): { [key: string]: boolean } | null => {
if(control.value && elements.find(element =>
element.alias === control.value
)) {
return { 'alias': true };
}
return null;
}
}
// TODO need to be fixed
generateAlias(name: string): string {
let alias = name.toLowerCase();
while (alias.includes(' / ') || alias.includes(' ')) {
alias = alias.replace(' / ', '-');
alias = alias.replace(' ', '-');
}
return alias;
}
} }
export class IndicatorUtils { export class IndicatorUtils {