import { AfterViewInit, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild } from "@angular/core"; import { Indicator, IndicatorPath, IndicatorType, Section, Stakeholder, Visibility } from "../openaireLibrary/monitor/entities/stakeholder"; import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils"; import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms"; import {AlertModal} from "../openaireLibrary/utils/modal/alert"; import {StatisticsService} from "../utils/services/statistics.service"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser"; import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service"; import {EnvProperties} from "../openaireLibrary/utils/properties/env-properties"; import {Subscriber} from "rxjs"; import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; import {Option} from "../openaireLibrary/dashboard/sharedComponents/input/input.component"; import {Router} from "@angular/router"; import {Session} from "../openaireLibrary/login/utils/helper.class"; import {UserManagementService} from "../openaireLibrary/services/user-management.service"; declare var UIkit; @Component({ selector: 'indicators', templateUrl: './indicators.component.html' }) export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterViewInit { @Input() public properties: EnvProperties = null; @Input() public topicIndex: number = 0; @Input() public categoryIndex: number = 0; @Input() public subcategoryIndex: number = 0; public stakeholder: Stakeholder = null; public user = null; public preview: string; public indicatorUtils: IndicatorUtils = new IndicatorUtils(); public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); public numberIndicatorFb: FormGroup; public chartIndicatorFb: FormGroup; public chartSections: FormArray; public numberSections: FormArray; /** * Editable indicator */ 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 */ public filters: FormGroup; public all: Option = { value: 'all', label: 'All' }; /** * Toggles */ // public grid: boolean = true; public editing: boolean = false; /** Safe Urls*/ public safeUrls: Map = new Map([]); private subscriptions: any[] = []; private urlSubscriptions: any[] = []; @ViewChild('editChartModal') editChartModal: AlertModal; @ViewChild('editNumberModal') editNumberModal: AlertModal; @ViewChild('deleteModal') deleteModal: AlertModal; //@ViewChild('deleteAllModal') deleteAllModal: AlertModal; //@ViewChild('deleteAndDisconnectModal') deleteAndDisconnectModal: AlertModal; //@ViewChild('deleteChartSectionModal') deleteChartSectionModal: AlertModal; //@ViewChild('deleteNumberSectionModal') deleteNumberSectionModal: AlertModal; @ViewChild('deleteSectionModal') deleteSectionModal: AlertModal; public sectionTypeToDelete: string; public sectionChildrenActionOnDelete: string; public indicatorChildrenActionOnDelete: string; urlParameterizedMessage = ""; constructor(private layoutService: LayoutService, private stakeholderService: StakeholderService, private statisticsService: StatisticsService, private userManagementService: UserManagementService, private fb: FormBuilder, private router: Router, private cdr: ChangeDetectorRef, private sanitizer: DomSanitizer) { } ngOnInit(): void { this.userManagementService.getUserInfo().subscribe(user => { this.user = user; }); this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => { this.stakeholder = stakeholder; if(this.stakeholder) { this.buildFilters(); this.buildSections(); this.filterCharts(); this.filterNumbers(); this.setPreview(); } }); } ngOnDestroy(): void { this.subscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } else if (value instanceof Function) { value(); } }); } ngAfterViewInit(): void { this.initReorder(); } ngOnChanges(changes: SimpleChanges): void { if (this.canEdit) { if (changes.topicIndex || changes.categoryIndex || changes.subcategoryIndex) { this.buildFilters(); this.initReorder(); } this.filterCharts(); this.filterNumbers(); } this.setPreview(); } 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; } } } } } initReorder() { this.subscriptions.forEach(value => { if (value instanceof Function) { value(); } }); if (document !== undefined) { let callback = (list, type: IndicatorType): void => { let items: HTMLCollection = list.current.children; let reordered = []; for (let i = 0; i < items.length; i++) { if (items.item(i).id) { reordered.push(items.item(i).id); } } this.reorderIndicators(list.current.id.toString().split('-')[1], type, reordered); }; this.numbers.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'moved', '#number-' + section._id, (list): void => { callback(list, "number"); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#number-' + section._id, (list): void => { callback(list, "number"); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#number-' + section._id, (list): void => { callback(list, "number"); })); }); this.charts.forEach((section) => { this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart-' + section._id, (list): void => { callback(list, "chart"); })); this.subscriptions.push(UIkit.util.on(document, 'added', '#chart-' + section._id, (list): void => { callback(list, "chart"); })); this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart-' + section._id, (list): void => { callback(list, "chart"); })); }); } } hide(element: any) { UIkit.dropdown(element).hide(); } private buildFilters() { this.filters = this.fb.group({ chartType: this.fb.control('all'), status: this.fb.control('all'), keyword: this.fb.control('') }); 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), stakeholderAlias: this.fb.control(section.stakeholderAlias), defaultId: this.fb.control(section.defaultId), type: this.fb.control(section.type), indicators: this.fb.control(section.indicators) })); }); this.chartSections = this.fb.array([]); this.charts.forEach(section => { this.chartSections.push(this.fb.group({ _id: this.fb.control(section._id), title: this.fb.control(section.title), stakeholderAlias: this.fb.control(section.stakeholderAlias), defaultId: this.fb.control(section.defaultId), 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); if (!this.safeUrls.get('url')) { indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); this.safeUrls.set(url, indicatorPath.safeResourceUrl); } }); }) }); this.buildSections(); } filterNumbers() { this.displayNumbers = this.filterStatus( this.filterByKeyword(HelperFunctions.copy(this.numbers), this.filters.value.keyword), this.filters.value.status); this.buildSections(); } 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; } get charts(): Section[] { if (this.stakeholder.topics[this.topicIndex] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts; } else { return []; } } 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] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]) { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers; } else { return []; } } set numbers(sections: Section[]) { this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers = sections; } get open(): boolean { 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] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex] && this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]; } public get numberIndicatorPaths(): FormArray { return this.numberIndicatorFb.get('indicatorPaths') as FormArray; } public get chartIndicatorPaths(): FormArray { return this.chartIndicatorFb.get('indicatorPaths') as FormArray; } public addJsonPath(index: number) { if(index==0 && this.getJsonPath(index).getRawValue()[index].indexOf(",")!=-1){ //if in the first path there are more than one paaths comma separated, split them and autogenerate the forms let paths = this.getJsonPath(index).getRawValue()[index].split(","); for(let i = 0; i< paths.length; i++){ if(i !=0){ this.getJsonPath(index).push(this.fb.control('', Validators.required)); } } this.getJsonPath(index).setValue(paths) return; } this.getJsonPath(index).push(this.fb.control('', Validators.required)); } public removeJsonPath(i: number, j:number) { this.getJsonPath(i).removeAt(j); } public getJsonPath(index: number): FormArray { return this.numberIndicatorPaths.at(index).get('jsonPath') as FormArray; } public getParameters(index: number): FormArray { return this.chartIndicatorPaths.at(index).get('parameters') as FormArray; } public getParameter(index: number, key: string): FormControl { return this.getParameters(index).controls.filter(control => control.value.key === key)[0] as FormControl; } private getSecureUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.sanitizer.bypassSecurityTrustResourceUrl( this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath))); } private getUrlByStakeHolder(indicatorPath: IndicatorPath) { return this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)); } public addNumberIndicatorPath(url: string = '',parameters: FormArray = new FormArray([]), source: string = 'search', jsonPath: FormArray = new FormArray([])) { if(jsonPath.length === 0) { jsonPath.push(this.fb.control('', Validators.required)); } this.numberIndicatorPaths.push(this.fb.group({ url: this.fb.control(url, Validators.required), jsonPath: jsonPath, // parameters: parameters, source: this.fb.control(source, Validators.required) } )); for(let index = 0; index < this.numberIndicatorPaths.length; index++) { this.subscriptions.push(this.numberIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.numberIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(value), value, this.stakeholder,this.numberIndicatorPaths.at(index).get('jsonPath').value ); if((indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_name") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") ==-1 ) || (!indicatorPath.chartObject && indicatorPath.url.indexOf("index_id") ==-1 && indicatorPath.url.indexOf("index_name") ==-1 && (indicatorPath.url).indexOf("index_shortName") ==-1 )){ // default profile if(this.stakeholder.defaultId == null){ this.urlParameterizedMessage = "This indicator couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." }else{ this.urlParameterizedMessage = "This indicator couldn't be generated properly. Please make sure chart data is for the current stakeholder." } }else { this.urlParameterizedMessage = ""; } /* if(value != indicatorPath.url) { (this.numberIndicatorPaths.at(index) as FormGroup).get('url').setValue( indicatorPath.url); }*/ if (!this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index] = indicatorPath; } else { this.indicator.indicatorPaths[index] = indicatorPath; } (this.numberIndicatorPaths.at(index) as FormGroup).get('source').setValue(indicatorPath.source); } }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('jsonPath').valueChanges.subscribe(value => { if (!this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index].jsonPath = value; } else { this.indicator.indicatorPaths[index].jsonPath = value; } }) ); this.subscriptions.push(this.numberIndicatorPaths.at(index).get('source').valueChanges.subscribe(value => { if (!this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index].source = value; } else { this.indicator.indicatorPaths[index].source = value; } }) ); } } public addChartIndicatorPath(value: string = '', parameters: FormArray = new FormArray([]), disableUrl: boolean = false, type:string=null) { this.chartIndicatorPaths.push(this.fb.group({ url: this.fb.control(value, [Validators.required, Validators.pattern('https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.' + '[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.' + '[a-zA-Z0-9]+\.[^\s]{2,}')]), parameters: parameters, type: this.fb.control(type) } )); if(disableUrl) { for(let index = 0; index < this.chartIndicatorPaths.length; index++) { this.chartIndicatorPaths.at(index).get('url').disable(); } } else { for(let index = 0; index < this.chartIndicatorPaths.length; index++) { this.urlSubscriptions.push(this.chartIndicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.chartIndicatorPaths.at(index).get('url').valid) { let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(value), value, this.chartIndicatorPaths.at(index).get('type').value, this.stakeholder); if(indicatorPath.chartObject && Object.keys(indicatorPath.parameters).indexOf("index_id") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_name") ==-1 && Object.keys(indicatorPath.parameters).indexOf("index_shortName") ==-1 ){ // default profile if(this.stakeholder.defaultId == null){ this.urlParameterizedMessage = "This chart couldn't be generated properly. Stakeholders based on this profile may not inherit the data correctly." }else{ this.urlParameterizedMessage = "This chart couldn't be generated properly. Please make sure chart data is for the current stakeholder." } }else { this.urlParameterizedMessage = ""; } (this.chartIndicatorPaths.at(index) as FormGroup).get('type').setValue(indicatorPath.type); let parameters = this.getParametersAsFormArray(indicatorPath); (this.chartIndicatorPaths.at(index) as FormGroup).setControl('parameters', parameters); if (!this.indicator.indicatorPaths[index]) { this.indicator.indicatorPaths[index] = indicatorPath; this.indicator.indicatorPaths[index].safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); } else { indicatorPath.safeResourceUrl = this.indicator.indicatorPaths[index].safeResourceUrl; this.indicator.indicatorPaths[index] = indicatorPath; } } }) ); } } } private getJsonPathAsFormArray(indicatorPath: IndicatorPath): FormArray { let jsonPath = this.fb.array([]); if (indicatorPath.jsonPath) { indicatorPath.jsonPath.forEach(path => { jsonPath.push(this.fb.control(path, Validators.required)); }); } return jsonPath; } private getParametersAsFormArray(indicatorPath: IndicatorPath): FormArray { let parameters = this.fb.array([]); if (indicatorPath.parameters) { Object.keys(indicatorPath.parameters).forEach(key => { if (this.indicatorUtils.ignoredParameters.indexOf(key) === -1) { if (this.indicatorUtils.parametersValidators.has(key)) { parameters.push(this.fb.group({ key: this.fb.control(key), value: this.fb.control(indicatorPath.parameters[key], this.indicatorUtils.parametersValidators.get(key)) })); } else { parameters.push(this.fb.group({ key: this.fb.control(key), value: this.fb.control(indicatorPath.parameters[key]) })); } } }); } return parameters; } public editNumberIndicatorOpen(section: Section, id = null) { this.urlParameterizedMessage = ""; this.section = section; this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; if (this.index !== -1) { this.indicator = HelperFunctions.copy(this.section.indicators[this.index]); this.numberIndicatorFb = this.fb.group({ _id: this.fb.control(this.indicator._id), name: this.fb.control(this.indicator.name, Validators.required), description: this.fb.control(this.indicator.description), additionalDescription: this.fb.control(this.indicator.additionalDescription), visibility: this.fb.control(this.indicator.visibility), indicatorPaths: this.fb.array([], Validators.required), type: this.fb.control(this.indicator.type), width: this.fb.control(this.indicator.width), defaultId: this.fb.control(this.indicator.defaultId) }); this.indicator.indicatorPaths.forEach(indicatorPath => { this.addNumberIndicatorPath(this.statisticsService.getNumberUrl(indicatorPath.source,this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)),indicatorPath.parameters, indicatorPath.source, this.getJsonPathAsFormArray(indicatorPath)); }); } else { this.indicator = new Indicator('', '', '','number', 'small', "PUBLIC", []); this.numberIndicatorFb = this.fb.group({ _id: this.fb.control(this.indicator._id), name: this.fb.control(this.indicator.name, Validators.required), description: this.fb.control(this.indicator.description), additionalDescription: this.fb.control(this.indicator.additionalDescription), visibility: this.fb.control(this.indicator.visibility), indicatorPaths: this.fb.array([], Validators.required), type: this.fb.control(this.indicator.type), width: this.fb.control(this.indicator.width), defaultId: this.fb.control(this.indicator.defaultId) }); this.addNumberIndicatorPath(); } this.editNumberModal.cancelButtonText = 'Cancel'; this.editNumberModal.okButtonLeft = false; this.editNumberModal.alertMessage = false; if (this.index === -1) { this.editNumberModal.alertTitle = 'Create a new number indicator'; this.editNumberModal.okButtonText = 'Save'; } else { this.editNumberModal.alertTitle = 'Edit number indicator\'s information'; this.editNumberModal.okButtonText = 'Save Changes'; } this.editNumberModal.open(); } public editChartIndicatorOpen(section: Section, id = null) { this.urlParameterizedMessage = ""; this.urlSubscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } }); this.section = section; this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; if (this.index !== -1) { this.indicator = HelperFunctions.copy(this.section.indicators[this.index]); this.chartIndicatorFb = this.fb.group({ _id: this.fb.control(this.indicator._id), name: this.fb.control(this.indicator.name), description: this.fb.control(this.indicator.description), additionalDescription: this.fb.control(this.indicator.additionalDescription), visibility: this.fb.control(this.indicator.visibility), indicatorPaths: this.fb.array([]), width: this.fb.control(this.indicator.width), defaultId: this.fb.control(this.indicator.defaultId) }); this.indicator.indicatorPaths.forEach(indicatorPath => { this.addChartIndicatorPath(this.getUrlByStakeHolder(indicatorPath), this.getParametersAsFormArray(indicatorPath), this.indicator.defaultId !== null, indicatorPath.type); indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); }); } else { this.indicator = new Indicator('', '', '', 'chart', 'medium', "PUBLIC",[]); this.chartIndicatorFb = this.fb.group({ _id: this.fb.control(this.indicator._id), name: this.fb.control(this.indicator.name), description: this.fb.control(this.indicator.description), additionalDescription: this.fb.control(this.indicator.additionalDescription), visibility: this.fb.control(this.indicator.visibility), indicatorPaths: this.fb.array([]), width: this.fb.control(this.indicator.width, Validators.required), defaultId: this.fb.control(this.indicator.defaultId) }); this.addChartIndicatorPath(); } this.editChartModal.cancelButtonText = 'Cancel'; this.editChartModal.okButtonLeft = false; this.editChartModal.alertMessage = false; if (this.index === -1) { this.editChartModal.alertTitle = 'Create a new chart indicator'; this.editChartModal.okButtonText = 'Save'; } else { this.editChartModal.alertTitle = 'Edit chart indicator\'s information'; this.editChartModal.okButtonText = 'Save Changes'; } this.editChartModal.open(); } saveIndicator() { this.editing = true; if (this.indicator.type === 'chart') { this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, true); this.section = this.charts.find(section => section._id === this.section._id); } else { this.indicator = this.indicatorUtils.generateIndicatorByForm(this.numberIndicatorFb.value, this.indicator.indicatorPaths, this.indicator.type, false); this.section = this.numbers.find(section => section._id === this.section._id); } console.debug("Indicator to svae"); console.debug(this.indicator); let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, this.section._id ]; this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.indicator, path).subscribe(indicator => { if (this.index !== -1) { this.section.indicators[this.index] = indicator; } else { this.section.indicators.push(indicator); } if(this.indicator.type === "chart") { this.filterCharts(); this.chartIndicatorFb = null; } else { this.filterNumbers(); this.numberIndicatorFb = null; } UIkit.notification('Indicator has been successfully saved', { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { this.chartIndicatorFb = null; UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } reorderIndicators(sectionId: string, type: IndicatorType, indicatorIds: string[]) { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, sectionId ]; this.stakeholderService.reorderIndicators(this.properties.monitorServiceAPIURL, path, indicatorIds, type).subscribe(indicators => { if (type === 'chart') { this.charts.find(section => section._id === sectionId).indicators = indicators; this.filterCharts(); } else { this.numbers.find(section => section._id === sectionId).indicators = indicators; this.filterNumbers(); } this.editing = false; }); } hasDifference(index: number): boolean { let hasDifference = false; this.chartIndicatorPaths.at(index).value.parameters.forEach((parameter) => { if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { hasDifference = true; return; } }); return hasDifference || this.indicator.indicatorPaths[index].safeResourceUrl.toString() !== this.getSecureUrlByStakeHolder(this.indicator.indicatorPaths[index]).toString(); } public get isAdministrator(): boolean { return Session.isPortalAdministrator(this.user) || Session.isMonitorCurator(this.user) || Session.isCommunityCurator(this.user) } refreshIndicator() { this.indicator = this.indicatorUtils.generateIndicatorByForm(this.chartIndicatorFb.value, this.indicator.indicatorPaths,'chart', true); this.indicator.indicatorPaths.forEach(indicatorPath => { indicatorPath.safeResourceUrl = this.getSecureUrlByStakeHolder(indicatorPath); }); } deleteIndicatorOpen(section: Section, indicatorId: string, type: string, childrenAction: string = null) { this.indicatorChildrenActionOnDelete = null; if(childrenAction == "delete") { this.indicatorChildrenActionOnDelete = childrenAction; } else if(childrenAction == "disconnect") { this.indicatorChildrenActionOnDelete = childrenAction; } this.section = section; if (type === 'chart') { this.index = this.charts.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId); } else { this.index = this.numbers.find(value => value._id == section._id).indicators.findIndex(value => value._id == indicatorId); } this.indicator = section.indicators.find(value => value._id == indicatorId); this.deleteModal.alertTitle = 'Delete indicator'; this.deleteModal.cancelButtonText = 'No'; this.deleteModal.okButtonText = 'Yes'; this.deleteModal.open(); } deleteIndicator() { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, this.section._id, this.indicator._id ]; 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(); } else { this.numbers.find(section => section._id === this.section._id).indicators.splice(this.index, 1); this.filterNumbers(); } UIkit.notification('Indicator has been successfully deleted', { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } toggleIndicatorStatus(sectionId: string, indicator: Indicator, visibility:Visibility) { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, sectionId, indicator._id ]; this.stakeholderService.toggleVisibility(this.properties.monitorServiceAPIURL, path, visibility).subscribe(visibility => { indicator.visibility = visibility; UIkit.notification('Indicator has been successfully changed to ' + visibility.toLowerCase, { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } /*toggleIndicatorAccess(sectionId: string, indicator: Indicator) { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, sectionId, indicator._id ]; this.stakeholderService.toggleAccess(this.properties.monitorServiceAPIURL, path).subscribe(visibility => { indicator.visibility = visibility; UIkit.notification('Indicator has been successfully changed to ' + (visibility?'public':'private'), { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); }*/ saveSection(section: Section, index: number, type: IndicatorType = "chart") { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id ]; this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, section, path, index).subscribe(section => { if (type === 'chart') { this.charts[index] = section; this.filterCharts(); } else { this.numbers[index] = section; this.filterNumbers(); } this.initReorder(); UIkit.notification('Section has been successfully saved', { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } createSection(index = -1, type: IndicatorType = 'chart') { this.editing = true; this.section = new Section(type, null, null, this.stakeholder.alias); let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id ]; this.stakeholderService.saveSection(this.properties.monitorServiceAPIURL, this.section, path, index).subscribe(section => { if (type === 'chart') { if (index !== -1) { this.charts.splice(index, 0, section); } else { this.charts.push(section); } this.filterCharts(); } else { if (index !== -1) { this.numbers.splice(index, 0, section); } else { this.numbers.push(section); } this.filterNumbers(); } this.initReorder(); UIkit.notification('Section has been successfully created', { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } // deleteNumberSectionOpen(section: Section, index: number) { // this.section = section; // this.index = index; // this.deleteNumberSectionModal.alertTitle = 'Delete Section'; // this.deleteNumberSectionModal.cancelButtonText = 'No'; // this.deleteNumberSectionModal.okButtonText = 'Yes'; // this.deleteNumberSectionModal.open(); // } // // deleteChartSectionOpen(section: Section, index: number) { // this.section = section; // this.index = index; // this.deleteChartSectionModal.alertTitle = 'Delete Section'; // this.deleteChartSectionModal.cancelButtonText = 'No'; // this.deleteChartSectionModal.okButtonText = 'Yes'; // this.deleteChartSectionModal.open(); // } deleteSectionOpen(section: Section, index: number, type: IndicatorType, childrenAction: string = null) { this.sectionTypeToDelete = type; this.sectionChildrenActionOnDelete = null; if(childrenAction == "delete") { this.sectionChildrenActionOnDelete = childrenAction; } else if(childrenAction == "disconnect") { this.sectionChildrenActionOnDelete = childrenAction; } this.section = section; this.index = index; this.deleteSectionModal.alertTitle = 'Delete Section'; this.deleteSectionModal.cancelButtonText = 'No'; this.deleteSectionModal.okButtonText = 'Yes'; this.deleteSectionModal.open(); } deleteSection() { this.editing = true; let path = [ this.stakeholder._id, this.stakeholder.topics[this.topicIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex]._id, this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex]._id, this.section._id ]; this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path, this.sectionChildrenActionOnDelete).subscribe(() => { if (this.sectionTypeToDelete === "chart") { this.charts.splice(this.index, 1); this.filterCharts(); } else { this.numbers.splice(this.index, 1); this.filterNumbers(); } this.initReorder(); UIkit.notification('Section has been successfully deleted', { status: 'success', timeout: 3000, pos: 'top-left' }); this.editing = false; }, error => { UIkit.notification(error.error.message, { status: 'danger', timeout: 3000, pos: 'top-left' }); this.editing = false; }); } }