Indicator Component: Remove filters. Cache number responses. Fix bug with delete save in subcategories.

This commit is contained in:
Konstantinos Triantafyllou 2021-11-24 19:31:33 +02:00
parent e418fea31f
commit 3e11718df1
6 changed files with 187 additions and 298 deletions

@ -1 +1 @@
Subproject commit 7ef741c205a3659e28d1f8521a37e2cc0d969de5
Subproject commit 130691b60a432b8432b610b1e201d1b4db251c12

View File

@ -1,7 +1,7 @@
<div *ngIf="stakeholder && canEdit">
<div *ngIf="numberSections">
<h6 class="uk-text-bold">Number Indicators</h6>
<ng-template ngFor [ngForOf]="displayNumbers" let-number let-i="index">
<ng-template ngFor [ngForOf]="numbers" let-number let-i="index">
<div [id]="'number-' + number._id"
class="uk-grid-match uk-grid-small uk-grid uk-margin-top section"
uk-sortable="group: number" uk-grid>
@ -43,10 +43,8 @@
</div>
<ng-template ngFor [ngForOf]="number.indicators" let-indicator let-j="index">
<div *ngIf="indicator" [id]="indicator._id"
[ngClass]="getNumberClassBySize(indicator.width)"
[class.disable-sortable]="!canReorder"
[class.uk-sortable-nodrag]="!canReorder">
<div class="uk-card uk-card-default uk-flex uk-flex-column uk-flex-center uk-position-relative" [class.uk-card-hover]="canReorder">
[ngClass]="getNumberClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-flex uk-flex-column uk-flex-center uk-position-relative uk-card-hover">
<div class="uk-card-body">
<ng-container
*ngTemplateOutlet="visibilityOptions; context:{indicator: indicator, sectionId: number._id}"></ng-container>
@ -124,7 +122,7 @@
</div>
<div *ngIf="chartSections" class="uk-margin-large-top">
<h6 class="uk-text-bold">Chart Indicators</h6>
<ng-template ngFor [ngForOf]="displayCharts" let-chart let-i="index">
<ng-template ngFor [ngForOf]="charts" let-chart let-i="index">
<div [id]="'chart-' + chart._id"
class="uk-grid-match section uk-grid-small uk-grid uk-margin-top"
uk-sortable="group: chart" uk-grid>
@ -166,10 +164,8 @@
</div>
<ng-template ngFor [ngForOf]="chart.indicators" let-indicator let-j="index">
<div *ngIf="indicator" [id]="indicator._id"
[ngClass]="getChartClassBySize(indicator.width)"
[class.disable-sortable]="!canReorder"
[class.uk-sortable-nodrag]="!canReorder">
<div class="uk-card uk-card-default uk-card-body uk-position-relative" [class.uk-card-hover]="canReorder">
[ngClass]="getChartClassBySize(indicator.width)">
<div class="uk-card uk-card-default uk-card-body uk-position-relative uk-card-hover">
<ng-container
*ngTemplateOutlet="visibilityOptions; context:{indicator: indicator, sectionId: chart._id}"></ng-container>
<div

View File

@ -25,7 +25,7 @@ import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser";
import {Reorder, StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties";
import {Subscriber} from "rxjs";
import {Observable, Subscriber, Subscription} from "rxjs";
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {Router} from "@angular/router";
import {Role, Session, User} from "../openaireLibrary/login/utils/helper.class";
@ -35,6 +35,8 @@ import {Notification} from "../openaireLibrary/notifications/notifications";
import {NotificationUtils} from "../openaireLibrary/notifications/notification-utils";
import {NotifyFormComponent} from "../openaireLibrary/notifications/notify-form/notify-form.component";
import {NotificationService} from "../openaireLibrary/notifications/notification.service";
import {properties} from "../../environments/environment";
import {response} from "express";
declare var UIkit;
@ -46,15 +48,17 @@ declare var UIkit;
export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit {
filesToUpload: Array<File>;
errorMessage = "";
@Input()
public properties: EnvProperties = null;
public properties: EnvProperties = properties;
@Input()
public topicIndex: number = 0;
@Input()
public categoryIndex: number = 0;
@Input()
public subcategoryIndex: number = 0;
@Input()
public stakeholder: Stakeholder = null;
@Input()
public changed: Observable<void>;
public user: User = null;
public preview: string;
public indicatorUtils: IndicatorUtils = new IndicatorUtils();
@ -69,44 +73,33 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
public section: Section;
public indicator: Indicator;
public index: number = -1;
/**
* Displayed chart and numbers base on Top filters
*/
public displayCharts: Section[] = [];
public displayNumbers: Section[] = [];
/**
* Top filters
*/
@Input()
public filters: FormGroup;
public editing: boolean = false;
/** Safe Urls*/
/** Caches */
public safeUrls: Map<string, SafeResourceUrl> = new Map<string, SafeResourceUrl>([]);
public numberResponses: Map<string, any> = new Map<string, any>();
public numberResults: Map<string, number> = new Map<string, number>();
/** Import / Export Indicators */
importLoading: boolean = false;
exportLoading: boolean = false;
private subscriptions: any[] = [];
private urlSubscriptions: any[] = [];
@ViewChild('editChartModal', {static: true}) editChartModal: AlertModal;
@ViewChild('editNumberModal', {static: true}) editNumberModal: AlertModal;
@ViewChild('deleteModal', {static: true}) deleteModal: AlertModal;
//@ViewChild('deleteAllModal') deleteAllModal: AlertModal;
//@ViewChild('deleteAndDisconnectModal') deleteAndDisconnectModal: AlertModal;
//@ViewChild('deleteChartSectionModal') deleteChartSectionModal: AlertModal;
//@ViewChild('deleteNumberSectionModal') deleteNumberSectionModal: AlertModal;
@ViewChild('deleteSectionModal', {static: true}) deleteSectionModal: AlertModal;
public sectionTypeToDelete: string;
public sectionChildrenActionOnDelete: string;
public indicatorChildrenActionOnDelete: string;
private firstLoad: boolean = true;
urlParameterizedMessage = null;
showCheckForSchemaEnhancements: boolean = false;
private notification: Notification;
@ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent;
@ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent;
@ViewChild('deleteNotify', {static: true}) deleteNotify: NotifyFormComponent;
/**
* Subscriptions
**/
private subscriptions: any[] = [];
private urlSubscriptions: any[] = [];
private numberSubscription: any[] = [];
constructor(private layoutService: LayoutService,
private stakeholderService: StakeholderService,
@ -124,17 +117,15 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
this.user = user;
}));
this.subscriptions.push(this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
this.stakeholder = stakeholder;
if (this.stakeholder && this.firstLoad) {
this.buildFilters();
this.buildSections();
this.filterCharts();
this.filterNumbers();
this.setPreview();
this.firstLoad = false;
}
}));
if (this.stakeholder) {
this.setCharts();
this.setNumbers();
}
this.changed.subscribe(() => {
this.setCharts();
this.setNumbers();
this.initReorder();
})
}
ngOnDestroy(): void {
@ -150,6 +141,11 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
value.unsubscribe();
}
});
this.numberSubscription.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
}
ngAfterViewInit(): void {
@ -159,63 +155,9 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
ngOnChanges(changes: SimpleChanges): void {
if (this.canEdit) {
if (changes.topicIndex || changes.categoryIndex || changes.subcategoryIndex) {
this.buildSections();
this.buildFilters();
this.initReorder();
}
this.filterCharts();
this.filterNumbers();
}
this.setPreview();
}
setNumberIndicators() {
this.numberResults.clear();
let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>();
this.numbers.forEach((section, i) => {
section.indicators.forEach((number, j) => {
let url = this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, number.indicatorPaths[0]);
const pair = JSON.stringify([number.indicatorPaths[0].source, url]);
const indexes = urls.get(pair) ? urls.get(pair) : [];
indexes.push([i, j]);
urls.set(pair, indexes);
});
});
urls.forEach((indexes, pair) => {
pair = JSON.parse(pair);
this.subscriptions.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(pair[0]), pair[1]).subscribe(response => {
indexes.forEach(([i, j]) => {
let result = JSON.parse(JSON.stringify(response));
this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => {
if (result) {
result = result[jsonPath];
}
});
if (typeof result === 'string' || typeof result === 'number') {
result = Number(result);
if (result === Number.NaN) {
result = 0;
}
} else {
result = 0;
}
this.numberResults.set(i + '-' + j, result);
});
}));
});
}
setPreview() {
if (this.stakeholder) {
this.preview = '/' + this.stakeholder.alias;
if (this.stakeholder.topics[this.topicIndex]) {
this.preview = '/' + this.stakeholder.alias + '/' + this.stakeholder.topics[this.topicIndex].alias;
if (this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]) {
this.preview += '/' + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].alias;
if (this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) {
this.preview += '/' + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].alias;
}
}
this.setCharts();
this.setNumbers();
}
}
}
@ -271,32 +213,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
UIkit.dropdown(element).hide();
}
private buildFilters() {
this.subscriptions.push(this.filters.get('chartType').valueChanges.subscribe(value => {
this.onChartTypeChange(value);
}));
this.subscriptions.push(this.filters.get('status').valueChanges.subscribe(value => {
this.onStatusChange(value);
}));
this.subscriptions.push(this.filters.get('keyword').valueChanges.subscribe(value => {
this.onKeywordChange(value);
}));
}
private buildSections() {
this.numberSections = this.fb.array([]);
this.numbers.forEach(section => {
this.numberSections.push(this.fb.group({
_id: this.fb.control(section._id),
title: this.fb.control(section.title),
creationDate: this.fb.control(section.creationDate),
stakeholderAlias: this.fb.control(section.stakeholderAlias),
defaultId: this.fb.control(section.defaultId),
type: this.fb.control(section.type),
indicators: this.fb.control(section.indicators)
}));
});
setCharts() {
this.chartSections = this.fb.array([]);
this.charts.forEach(section => {
this.chartSections.push(this.fb.group({
@ -308,16 +225,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
type: this.fb.control(section.type),
indicators: this.fb.control(section.indicators)
}));
});
}
filterCharts() {
this.displayCharts = this.filterChartType(
this.filterStatus(this.filterByKeyword(HelperFunctions.copy(this.charts), this.filters.value.keyword),
this.filters.value.status),
this.filters.value.chartType
);
this.displayCharts.forEach(section => {
section.indicators.forEach(indicator => {
indicator.indicatorPaths.forEach(indicatorPath => {
let url = this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath);
@ -328,60 +235,67 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
});
})
});
this.buildSections();
}
filterNumbers() {
this.displayNumbers = this.filterStatus(
this.filterByKeyword(HelperFunctions.copy(this.numbers), this.filters.value.keyword),
this.filters.value.status);
this.buildSections();
this.setNumberIndicators();
setNumbers() {
this.numberSections = this.fb.array([]);
this.numberResults.clear();
let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>();
this.numbers.forEach((section, i) => {
this.numberSections.push(this.fb.group({
_id: this.fb.control(section._id),
title: this.fb.control(section.title),
creationDate: this.fb.control(section.creationDate),
stakeholderAlias: this.fb.control(section.stakeholderAlias),
defaultId: this.fb.control(section.defaultId),
type: this.fb.control(section.type),
indicators: this.fb.control(section.indicators)
}));
section.indicators.forEach((number, j) => {
let url = this.indicatorUtils.getFullUrlWithFilters(this.stakeholder, number.indicatorPaths[0]);
const pair = JSON.stringify([number.indicatorPaths[0].source, url]);
const indexes = urls.get(pair) ? urls.get(pair) : [];
indexes.push([i, j]);
urls.set(pair, indexes);
});
});
this.numberSubscription.forEach(value => {
if (value instanceof Subscriber) {
value.unsubscribe();
}
});
urls.forEach((indexes, pair) => {
let parsed = JSON.parse(pair);
let response = this.numberResponses.get(pair);
if(response) {
this.calculateResults(response, indexes);
} else {
this.numberSubscription.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(parsed[0]), parsed[1]).subscribe(response => {
this.calculateResults(response, indexes);
this.numberResponses.set(pair, response);
}));
}
});
}
onChartTypeChange(value) {
this.displayCharts = this.filterChartType(HelperFunctions.copy(this.charts), value);
}
onStatusChange(value) {
this.displayCharts = this.filterStatus(HelperFunctions.copy(this.charts), value);
this.displayNumbers = this.filterStatus(HelperFunctions.copy(this.numbers), value);
}
onKeywordChange(value) {
this.displayCharts = this.filterByKeyword(HelperFunctions.copy(this.charts), value);
this.displayNumbers = this.filterByKeyword(HelperFunctions.copy(this.numbers), value);
}
private filterChartType(sections: Section[], value): Section[] {
if (value !== 'all') {
sections.forEach(section =>
section.indicators = section.indicators.filter(indicator =>
indicator.indicatorPaths.filter(indicatorPath => indicatorPath.type === value).length > 0));
}
return sections;
}
private filterStatus(sections: Section[], value): Section[] {
if (value !== 'all') {
sections.forEach(section =>
section.indicators = section.indicators.filter(indicator => indicator.visibility === value));
}
return sections;
}
private filterByKeyword(sections: Section[], value): Section[] {
if (value !== null && value !== '') {
sections.forEach(section =>
section.indicators = section.indicators.filter(indicator => (indicator.name && indicator.name.toLowerCase().includes(value.toLowerCase()))
|| (indicator.description && indicator.description.toLowerCase().includes(value.toLowerCase()))
|| (indicator.additionalDescription && indicator.additionalDescription.toLowerCase().includes(value.toLowerCase()))
|| indicator.indicatorPaths.filter(indicatorPath => (indicatorPath.parameters && indicatorPath.parameters.title &&
indicatorPath.parameters.title.includes(value.toLowerCase()))).length > 0));
}
return sections;
private calculateResults(response: any, indexes: [number, number][]) {
indexes.forEach(([i, j]) => {
let result = JSON.parse(JSON.stringify(response));
this.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => {
if (result) {
result = result[jsonPath];
}
});
if (typeof result === 'string' || typeof result === 'number') {
result = Number(result);
if (result === Number.NaN) {
result = 0;
}
} else {
result = 0;
}
this.numberResults.set(i + '-' + j, result);
});
}
get charts(): Section[] {
@ -394,10 +308,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
}
}
set charts(sections: Section[]) {
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts = sections;
}
get numbers(): Section[] {
if (this.stakeholder.topics[this.topicIndex] &&
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] &&
@ -416,11 +326,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
return this.layoutService.open;
}
get canReorder(): boolean {
return this.filters.value.chartType === 'all' &&
this.filters.value.status === 'all' && this.filters.value.keyword === '' && !this.editing;
}
get canEdit() {
return this.stakeholder &&
this.stakeholder.topics[this.topicIndex] &&
@ -862,11 +767,11 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
if (this.stakeholder.defaultId) {
this.notification.groups.push(Role.manager(this.stakeholder.type, this.stakeholder.alias));
if (this.indicator.type === "chart") {
this.filterCharts();
this.setCharts();
this.chartIndicatorFb = null;
this.editChartNotify.sendNotification(this.notification);
} else {
this.filterNumbers();
this.setNumbers();
this.numberIndicatorFb = null;
this.editNumberNotify.sendNotification(this.notification);
}
@ -876,11 +781,11 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.notification.groups.push(Role.manager(value.type, value.alias))
});
if (this.indicator.type === "chart") {
this.filterCharts();
this.setCharts();
this.chartIndicatorFb = null;
this.editChartNotify.sendNotification(this.notification);
} else {
this.filterNumbers();
this.setNumbers();
this.numberIndicatorFb = null;
this.editNumberNotify.sendNotification(this.notification);
}
@ -914,9 +819,8 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.stakeholderService.saveBulkElements(this.properties.monitorServiceAPIURL, indicators, path).subscribe(stakeholder => {
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts = stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts;
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers = stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers;
this.buildSections();
this.filterCharts();
this.filterNumbers();
this.setCharts();
this.setNumbers();
this.initReorder();
this.notification = NotificationUtils.importIndicators(this.user.fullname, this.stakeholder.alias);
this.notification.entity = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id;
@ -993,10 +897,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, reorder, type).subscribe(indicators => {
if (type === 'chart') {
this.charts.find(section => section._id === sectionId).indicators = indicators;
this.filterCharts();
this.setCharts();
} else {
this.numbers.find(section => section._id === sectionId).indicators = indicators;
this.filterNumbers();
this.setNumbers();
}
this.editing = false;
}));
@ -1065,10 +969,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.indicatorChildrenActionOnDelete).subscribe(() => {
if (this.indicator.type === 'chart') {
this.charts.find(section => section._id === this.section._id).indicators.splice(this.index, 1);
this.filterCharts();
this.setCharts();
} else {
this.numbers.find(section => section._id === this.section._id).indicators.splice(this.index, 1);
this.filterNumbers();
this.setNumbers();
}
UIkit.notification('Indicator has been <b>successfully deleted</b>', {
status: 'success',
@ -1140,10 +1044,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, section, path, index).subscribe(section => {
if (type === 'chart') {
this.charts[index] = section;
this.filterCharts();
this.setCharts();
} else {
this.numbers[index] = section;
this.filterNumbers();
this.setNumbers();
}
this.initReorder();
UIkit.notification('Section has been <b>successfully saved</b>', {
@ -1178,14 +1082,14 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
} else {
this.charts.push(section);
}
this.filterCharts();
this.setCharts();
} else {
if (index !== -1) {
this.numbers.splice(index, 0, section);
} else {
this.numbers.push(section);
}
this.filterNumbers();
this.setNumbers();
}
this.initReorder();
UIkit.notification('Section has been <b>successfully created</b>', {
@ -1253,10 +1157,10 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.sectionChildrenActionOnDelete).subscribe(() => {
if (this.sectionTypeToDelete === "chart") {
this.charts.splice(this.index, 1);
this.filterCharts();
this.setCharts();
} else {
this.numbers.splice(this.index, 1);
this.filterNumbers();
this.setNumbers();
}
this.initReorder();
UIkit.notification('Section has been <b>successfully deleted</b>', {
@ -1276,7 +1180,6 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
}
private checkForSchemaEnhancements(url: string) {
//new schema
this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url);
}
@ -1383,7 +1286,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
this.exportLoading = true;
let indicators = [];
let index: number = 0;
this.displayNumbers.forEach(section => {
this.charts.forEach(section => {
section.indicators.forEach(indicator => {
indicator.indicatorPaths.forEach(indicatorPath => {
// console.debug("export number: ", this.statisticsService.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)));
@ -1398,7 +1301,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV
});
});
this.displayCharts.forEach(section => {
this.charts.forEach(section => {
section.indicators.forEach(indicator => {
indicator.indicatorPaths.forEach(indicatorPath => {
// console.debug("export chart: " + this.getUrlByStakeHolder(indicatorPath));

View File

@ -113,7 +113,7 @@
visibility: stakeholder.topics[topicIndex].categories[i].visibility}">
</ng-container>
</span>
<a (click)="toggleCategory(i)">
<a (click)="chooseCategory(i)">
<span class="title"> {{category.name}}</span>
</a>
<span class="uk-invisible-hover" (click)="$event.stopPropagation();$event.preventDefault()">
@ -161,7 +161,7 @@
visibility: stakeholder.topics[topicIndex].categories[categoryIndex].subCategories[i].visibility}">
</ng-container>
</span>
<a (click)="chooseSubcategory(categoryIndex, i);$event.preventDefault()"
<a (click)="chooseSubcategory(i);$event.preventDefault()"
class="space">
<span>{{subCategory.name}}</span>
</a>
@ -199,7 +199,7 @@
<span class="uk-icon-button small portal-icon-button">
<icon name="add"></icon>
</span>
<span [class.uk-hidden-hover]="stakeholder.topics[topicIndex].categories[selectedCategoryIndex].subCategories.length > 0" class="space">Create new subcategory</span>
<span [class.uk-hidden-hover]="stakeholder.topics[topicIndex].categories[categoryIndex].subCategories.length > 0" class="space">Create new subcategory</span>
</span>
</li>
</ul>
@ -227,11 +227,9 @@
</div>
<div inner>
<input #file id="import-file" type="file" class="uk-hidden" (change)="indicators.fileChangeEvent($event)"/>
<indicators #indicators [properties]="properties"
[topicIndex]="topicIndex"
[categoryIndex]="categoryIndex"
[filters]="filters"
[subcategoryIndex]="subCategoryIndex"></indicators>
<indicators #indicators [topicIndex]="topicIndex" [categoryIndex]="categoryIndex"
[subcategoryIndex]="subCategoryIndex"
[stakeholder]="stakeholder" [changed]="change.asObservable()"></indicators>
</div>
</div>
<modal-alert #deleteModal (alertOutput)="deleteElement()">

View File

@ -2,26 +2,18 @@ import {Component, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {Title} from '@angular/platform-browser';
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
import {
Category,
Stakeholder,
SubCategory,
Topic,
Visibility
} from "../openaireLibrary/monitor/entities/stakeholder";
import {Category, Stakeholder, SubCategory, Topic, Visibility} from "../openaireLibrary/monitor/entities/stakeholder";
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class";
import {AlertModal} from "../openaireLibrary/utils/modal/alert";
import {Subscriber, Subscription} from "rxjs";
import {Subject, Subscriber, Subscription} from "rxjs";
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
import {StakeholderUtils} from "../utils/indicator-utils";
import {StringUtils} from "../openaireLibrary/utils/string-utils.class";
import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard";
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
import {Option} from "../openaireLibrary/sharedComponents/input/input.component";
import {properties} from "../../environments/environment";
import {IndicatorsComponent} from "./indicators.component";
import {Session} from "../openaireLibrary/login/utils/helper.class";
declare var UIkit;
@ -32,21 +24,24 @@ declare var UIkit;
export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
private subscriptions: any[] = [];
private paramsSub: any;
public properties: EnvProperties;
public properties: EnvProperties = properties;
public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
public loading: boolean = true;
public stakeholder: Stakeholder;
/**
* Stakeholder change event
* */
public change: Subject<void> = new Subject<void>();
/**
* Current topic
**/
public topicIndex: number = 0;
/**
* categoryIndex: Current category to be edited, selectedCategoryIndex: selected on menu(opened)
* Current category
*/
public categoryIndex: number = 0;
public selectedCategoryIndex: number = 0;
/**
* Current Subcategory to be edited
* Current Subcategory
*/
public subCategoryIndex: number = 0;
/**
@ -56,14 +51,10 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
public element: Topic | Category | SubCategory;
public type: 'topic' | 'category' | 'subcategory' = "topic";
public index: number = -1;
/**
* Check form validity
*/
public toggle: boolean = false;
@ViewChild('deleteModal', { static: true }) deleteModal: AlertModal;
@ViewChild('editModal', { static: true }) editModal: AlertModal;
@ViewChild('deleteModal', {static: true}) deleteModal: AlertModal;
@ViewChild('editModal', {static: true}) editModal: AlertModal;
public elementChildrenActionOnDelete: string;
public filters: FormGroup;
public all: Option = {
@ -81,38 +72,35 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
}
public ngOnInit() {
this.properties = properties;
let subscription: Subscription;
this.paramsSub = this.route.params.subscribe(params => {
if (subscription) {
subscription.unsubscribe();
let subscription: Subscription;
this.paramsSub = this.route.params.subscribe(params => {
if (subscription) {
subscription.unsubscribe();
}
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = stakeholder;
if (params['topic']) {
this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
} else {
this.topicIndex = 0;
}
subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
if (stakeholder) {
this.stakeholder = stakeholder;
if(params['topic']) {
this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']);
}else{
this.topicIndex = 0;
}
this.categoryIndex = 0;
this.subCategoryIndex = 0;
this.filters = this.fb.group({
chartType: this.fb.control('all'),
status: this.fb.control('all'),
keyword: this.fb.control('')
});
if (this.topicIndex === -1) {
this.navigateToError();
} else {
this.title.setTitle(stakeholder.name + " | Indicators");
this.toggle = true;
}
}
this.categoryIndex = 0;
this.subCategoryIndex = 0;
this.filters = this.fb.group({
chartType: this.fb.control('all'),
status: this.fb.control('all'),
keyword: this.fb.control('')
});
this.subscriptions.push(subscription);
});
if (this.topicIndex === -1) {
this.navigateToError();
} else {
this.title.setTitle(stakeholder.name + " | Indicators");
}
}
});
this.subscriptions.push(subscription);
});
}
public ngOnDestroy() {
@ -121,7 +109,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
value.unsubscribe();
}
});
if(this.paramsSub instanceof Subscriber) {
if (this.paramsSub instanceof Subscriber) {
this.paramsSub.unsubscribe();
}
}
@ -140,6 +128,10 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
UIkit.dropdown(element).hide();
}
stakeholderChanged() {
this.change.next();
}
public saveElement() {
if (this.type === "topic") {
this.saveTopic();
@ -244,18 +236,15 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
this.stakeholder.topics[this.index]._id
];
let callback = (): void => {
this.topicIndex = Math.max(0, this.index - 1);
this.stakeholder.topics.splice(this.index, 1);
};
this.delete('Topic has been successfully be deleted', path, callback, (this.topicIndex === this.index));
}
public toggleCategory(index: number) {
if (this.categoryIndex !== index) {
this.categoryIndex = index;
this.toggle = true;
} else {
this.toggle = !this.toggle;
}
public chooseCategory(index: number) {
this.categoryIndex = index;
this.subCategoryIndex = 0;
}
private buildCategory(category: Category) {
@ -340,13 +329,14 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
this.stakeholder.topics[this.topicIndex].categories[this.index]._id
];
let callback = (): void => {
this.categoryIndex = Math.max(0, this.index - 1);
this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1);
};
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);
let subCategories = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.filter(element => element._id !== subCategory._id);
this.form = this.fb.group({
_id: this.fb.control(subCategory._id),
name: this.fb.control(subCategory.name, Validators.required),
@ -379,7 +369,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
if (index === -1) {
this.buildSubcategory(new SubCategory(null, null, null, "PUBLIC"));
} else {
this.buildSubcategory(this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[index]);
this.buildSubcategory(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[index]);
}
this.editOpen();
}
@ -389,13 +379,13 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
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.categoryIndex]._id
];
let callback = (subCategory: SubCategory): void => {
if (this.index === -1) {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.push(subCategory);
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.push(subCategory);
} else {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index] = HelperFunctions.copy(subCategory);
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index] = HelperFunctions.copy(subCategory);
}
};
if (this.index === -1) {
@ -412,17 +402,17 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
let path = [
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
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id
];
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index], path, visibility);
this.changeStatus(this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index], path, visibility);
}
public deleteSubcategoryOpen(index, childrenAction: string = null) {
this.type = 'subcategory';
this.index = index;
this.element = this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index];
this.element = this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index];
this.deleteOpen(childrenAction);
}
@ -430,11 +420,12 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
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
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id,
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index]._id
];
let callback = (): void => {
this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.splice(this.index, 1);
this.subCategoryIndex = Math.max(0, this.index - 1);
this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories.splice(this.index, 1);
};
this.delete('Subcategory has been successfully be deleted', path, callback);
}
@ -476,6 +467,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
private save(message: string, path: string[], saveElement: any, callback: Function, redirect = false) {
this.subscriptions.push(this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, saveElement, path).subscribe(saveElement => {
callback(saveElement);
this.stakeholderChanged();
UIkit.notification(message, {
status: 'success',
timeout: 6000,
@ -498,6 +490,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
private delete(message: string, path: string[], callback: Function, redirect = false) {
this.subscriptions.push(this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.elementChildrenActionOnDelete).subscribe(() => {
callback();
this.stakeholderChanged();
UIkit.notification(message, {
status: 'success',
timeout: 6000,
@ -548,8 +541,7 @@ export class TopicComponent implements OnInit, OnDestroy, IDeactivateComponent {
});
}
chooseSubcategory(categoryIndex: number, subcategoryIndex: number) {
this.categoryIndex = categoryIndex;
chooseSubcategory(subcategoryIndex: number) {
this.subCategoryIndex = subcategoryIndex;
}

@ -1 +1 @@
Subproject commit 999d3833d3805534677aa741a3759e26e09b50f2
Subproject commit 28db142aa54b8bea87ada52dbae2da7c7da8f458