[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 {ActivatedRoute, NavigationEnd, RouteConfigLoadEnd, Router} from '@angular/router';
import {ActivatedRoute, NavigationEnd, Router} from '@angular/router';
import {EnvProperties} from './openaireLibrary/utils/properties/env-properties';
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_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required),
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),
isActive: this.fb.control(this.stakeholder.isActive),
type: this.fb.control(this.stakeholder.type, Validators.required),
@ -196,7 +202,7 @@ export class HomeComponent implements OnInit, OnDestroy {
public saveStakeholder() {
if (this.index === -1) {
if(!this.stakeholderFb.value.isDefaultProfile) {
if (!this.stakeholderFb.value.isDefaultProfile) {
// this.stakeholderFb.setValue(this.stakeholderUtils.
// createFunderFromDefaultProfile(this.stakeholderFb.value,
// 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.
*/
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.

View File

@ -13,7 +13,7 @@
[class.act_section]="item.open"
[title]="item.name"
[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 class="menu_title">{{item.name}}</span>
</a>

View File

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

View File

@ -8,7 +8,8 @@
<img class="badge "
src="assets/theme-assets/prototype_flag.svg"
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"
class="uk-logo uk-navbar-item ng-star-inserted uk-link uk-margin-small-top uk-margin-medium-left"
routerlink="/"
routerlinkactive="uk-link" href="/">
<img *ngIf="stakeholder.logoUrl" [src]="stakeholder.logoUrl" class="uk-responsive-height">
@ -18,12 +19,13 @@
</a>
<div class="uk-margin-large-left uk-width-medium ng-star-inserted">
<div class="">
<!-- <div dashboard-input label="Search for..." [formInput]="keyword"></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">
<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>
@ -57,7 +59,8 @@
<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"
<a (click)="navigateTo(stakeholder.alias, topic.alias)"
class="uk-margin-remove-bottom uk-h4"
><span>{{topic.name}}</span></a>
</li>
</ng-template>
@ -69,8 +72,7 @@
[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"
<div id="page_content" click-outside-or-esc targetId="page_content" [escClose]="false"
(clickOutside)="toggleOpen($event)">
<div id="page_content_inner">
<!-- <div>
@ -84,7 +86,8 @@
[(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 "
<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>
@ -96,21 +99,21 @@
</div>
</div>
</div>
<div *ngIf="activeSubCategory.description && activeSubCategory.description.length > 0 ||
activeCategory.description && activeCategory.description.length > 0 ||
activeTopic.description && activeTopic.description.length > 0"
<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 :
: (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">
<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'"
@ -128,7 +131,7 @@
</div>
</ng-template>
</div>
<div class="uk-grid uk-grid-medium uk-margin-bottom uk-flex uk-flex-bottom "
<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)"
@ -166,7 +169,7 @@
</div>
</div>
</div>
<a id="style_switcher" class="" routerLinkActive="active"
<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>

View File

@ -85,8 +85,8 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
this.status = this.errorCodes.LOADING;
this.numberResults = new Map<number, number>();
this.chartsActiveType = new Map<number, IndicatorPath>();
// this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
let stakeholder: Stakeholder = null;
this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
/*let stakeholder: Stakeholder = null;
if (params['stakeholder'] == "fwf") {
stakeholder = new Stakeholder(null, "funder", "fwf_________::FWF", "Austrian Science Fund (FWF)", "FWF",
false, "fwf", true, true, null);
@ -104,7 +104,7 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
false, "ec", true, true, null);
stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics);
stakeholder.logoUrl = "./assets/ec.png";
}
}*/
if (stakeholder) {
this.stakeholder = stakeholder;
this.seoService.createLinkForCanonicalURL(url, false);
@ -123,9 +123,9 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
this.status = this.errorCodes.DONE;
this.setView(params);
}
// }, error => {
// this.navigateToError();
// })
}, error => {
this.navigateToError();
})
} else {
this.setView(params);
}
@ -172,25 +172,27 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
}
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);
if (this.activeTopic) {
if (params['category']) {
this.activeCategory = this.activeTopic.categories.find(category =>
(category.alias === params['category']) && category.isPublic && category.isActive);
if(!this.activeCategory) {
this.navigateToError();
return;
}
} else {
this.activeCategory = this.activeTopic.categories.find(category => category.isPublic && category.isActive);
if (this.activeCategory) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
subCategory.isPublic && subCategory.isActive);
if (this.activeSubCategory) {
this.setSideBar();
if (this.activeSubCategory) {
this.setIndicators();
} else {
this.navigateToError();
}
} else {
this.navigateToError();
this.setSideBar();
}
return;
}
@ -198,6 +200,10 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
if (params['subCategory']) {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
(subCategory.alias === params['subCategory'] && subCategory.isPublic && subCategory.isActive));
if(!this.activeSubCategory) {
this.navigateToError();
return;
}
} else {
this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
subCategory.isPublic && subCategory.isActive);
@ -209,9 +215,13 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
this.navigateToError();
}
return;
} else {
this.activeSubCategory = null;
}
}
} else {
this.navigateToError();
return;
}
} else {
this.activeTopic = this.stakeholder.topics.find(topic => topic.isPublic && topic.isActive);
if (this.activeTopic) {
@ -254,6 +264,9 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent
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);
}

View File

@ -12,7 +12,7 @@ import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {Subscriber} from "rxjs";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {LayoutService} from "../library/sharedComponents/sidebar/layout.service";
import {IndicatorUtils} from "../utils/indicator-utils";
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
declare var UIkit;
@ -29,6 +29,7 @@ export class StakeholderComponent implements OnInit, OnDestroy {
private errorMessages: ErrorMessagesComponent;
public topicFb: FormGroup;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public element: any;
public index: number;
properties: EnvProperties;
@ -89,16 +90,30 @@ export class StakeholderComponent implements OnInit, OnDestroy {
}
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),
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 saveTopicOpen(element, index = -1) {
@ -116,9 +131,6 @@ export class StakeholderComponent implements OnInit, OnDestroy {
public saveTopic(element, index = -1) {
if (!this.topicFb.invalid) {
if (!this.topicFb.value.alias) {
this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
}
if (index === -1) {
this.save('Topic has been successfully created', element);
} else {
@ -148,7 +160,7 @@ export class StakeholderComponent implements OnInit, OnDestroy {
this.stakeholderService.setStakeholder(this.stakeholder);
UIkit.notification(message, {
status: 'success',
timeout: 3000000,
timeout: 3000,
pos: 'top-left'
});
this.hide(element);

View File

@ -76,7 +76,7 @@
<i class="md-icon material-icons">more_vert</i>
<div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal">
<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>
</ul>
</div>
@ -142,7 +142,7 @@
<i class="md-icon material-icons">more_vert</i>
<div uk-dropdown="mode: click; pos: bottom-right" class="uk-padding-remove-horizontal">
<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>
</ul>
</div>

View File

@ -292,7 +292,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.editIndicatorModal.open();
}
public createIndicator() {
public createChartIndicator() {
this.indicator = new Indicator(
this.indicatorFb.value.name,
this.indicatorFb.value.description,
@ -306,10 +306,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.indicator.indicatorPaths.push(
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;
if (this.index !== -1) {
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({
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),
isPublic: this.fb.control(this.indicator.isPublic),
isActive: this.fb.control(this.indicator.isActive),
indicatorPaths: indicatorPaths,
width: this.fb.control(this.indicator.width, Validators.required),
width: this.fb.control(this.indicator.width),
});
if(this.index === -1) {
this.editIndicatorModal.okButtonText = 'Save';
@ -365,7 +365,9 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
saveIndicator() {
if(this.indicator) {
if(this.indicator.type === 'chart') {
this.indicator = this.indicatorUtils.generateIndicatorByForm(this.indicatorFb.value, this.indicator.indicatorPaths);
}
let path = [
this.stakeholder._id,
this.stakeholder.topics[this.topicIndex]._id,
@ -385,7 +387,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.indicatorFb = null;
});
} else {
this.createIndicator();
this.createChartIndicator();
}
}

View File

@ -6,9 +6,9 @@ import {Category, Stakeholder, SubCategory, Topic} from "../utils/entities/stake
import {StakeholderService} from "../services/stakeholder.service";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {Subscriber} from "rxjs";
import {Subscriber, Subscription} from "rxjs";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {IndicatorUtils} from "../utils/indicator-utils";
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
declare var UIkit;
@ -20,6 +20,7 @@ export class TopicComponent implements OnInit, OnDestroy {
public subscriptions: any[] = [];
public properties: EnvProperties;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public loading: boolean = true;
public stakeholder: Stakeholder;
/**
@ -65,26 +66,30 @@ export class TopicComponent implements OnInit, OnDestroy {
this.route.data
.subscribe((data: { envSpecific: EnvProperties }) => {
this.properties = data.envSpecific;
this.route.params.subscribe( params => {
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
let subscription: Subscription;
this.subscriptions.push(this.route.params.subscribe(params => {
if(subscription) {
subscription.unsubscribe();
}
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = HelperFunctions.copy(stakeholder);
this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
if(this.topicIndex === -1) {
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) {
this.subscriptions.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
@ -99,20 +104,34 @@ export class TopicComponent implements OnInit, OnDestroy {
}
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),
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 editTopicOpen(element) {
if(element.className.indexOf('uk-open') !== -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
this.buildTopic(this.stakeholder.topics[this.topicIndex]);
@ -121,21 +140,18 @@ export class TopicComponent implements OnInit, OnDestroy {
}
public saveTopic(element) {
if(!this.topicFb.invalid) {
if(!this.topicFb.value.alias) {
this.topicFb.value.alias = this.topicFb.value.name.toLowerCase().trim();
}
if (!this.topicFb.invalid) {
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);
this.save('Topic has been successfully saved', element, path, this.topicFb.value, callback, true);
}
}
public deleteTopicOpen(name: string, element) {
this.deleteOpen(name,'topic', this.deleteTopicModal, element, this.topicIndex);
this.deleteOpen(name, 'topic', this.deleteTopicModal, element, this.topicIndex);
}
public deleteTopic() {
@ -151,7 +167,7 @@ export class TopicComponent implements OnInit, OnDestroy {
}
public toggleCategory(index: number) {
if(this.selectedCategoryIndex !== index) {
if (this.selectedCategoryIndex !== index) {
this.selectedCategoryIndex = index;
this.toggle = true;
} else {
@ -160,23 +176,37 @@ export class TopicComponent implements OnInit, OnDestroy {
}
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),
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) {
public editCategoryOpen(element, index: number = -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if(index === -1) {
if (index === -1) {
this.buildCategory(new Category(null, null, null, true, true));
} else {
this.buildCategory(this.stakeholder.topics[this.topicIndex].categories[index]);
@ -186,20 +216,17 @@ export class TopicComponent implements OnInit, OnDestroy {
}
public saveCategory(element, index = -1) {
if(!this.categoryFb.invalid) {
if(!this.categoryFb.value.alias) {
this.categoryFb.value.alias = this.categoryFb.value.name.toLowerCase();
}
if (!this.categoryFb.invalid) {
let path = [this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id];
let callback = (category: Category): void => {
if(index === -1) {
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) {
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);
@ -208,7 +235,7 @@ export class TopicComponent implements OnInit, OnDestroy {
}
public deleteCategoryOpen(name: string, element, index) {
this.deleteOpen(name,'category', this.deleteCategoryModal, element, index);
this.deleteOpen(name, 'category', this.deleteCategoryModal, element, index);
}
public deleteCategory() {
@ -225,54 +252,62 @@ export class TopicComponent implements OnInit, OnDestroy {
}
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),
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) {
public editSubCategoryOpen(element, index: number = -1) {
if (element.className.indexOf('uk-open') !== -1) {
this.hide(element);
} else {
if(index === -1) {
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.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();
}
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);
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.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[index] = subCategory;
}
this.stakeholderService.setStakeholder(this.stakeholder);
};
if(index === -1) {
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);
@ -282,7 +317,7 @@ export class TopicComponent implements OnInit, OnDestroy {
}
public deleteSubcategoryOpen(name: string, element, index) {
this.deleteOpen(name,'subcategory', this.deleteSubcategoryModal, element, index);
this.deleteOpen(name, 'subcategory', this.deleteSubcategoryModal, element, index);
}
public deleteSubcategory() {
@ -293,8 +328,7 @@ export class TopicComponent implements OnInit, OnDestroy {
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.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);
@ -322,7 +356,7 @@ export class TopicComponent implements OnInit, OnDestroy {
timeout: 3000,
pos: 'top-left'
});
if(redirect) {
if (redirect) {
this.router.navigate(['../' + saveElement.alias], {
relativeTo: this.route
});
@ -346,7 +380,7 @@ export class TopicComponent implements OnInit, OnDestroy {
timeout: 3000,
pos: 'top-left'
});
if(redirect) {
if (redirect) {
this.back();
}
this.hide(this.element);

View File

@ -1,5 +1,5 @@
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 {
icon?: string,
@ -84,6 +84,27 @@ export class StakeholderUtils {
}
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 {