diff --git a/src/app/openaireLibrary b/src/app/openaireLibrary index b8ac412..9939c27 160000 --- a/src/app/openaireLibrary +++ b/src/app/openaireLibrary @@ -1 +1 @@ -Subproject commit b8ac4121379c5294d1201932af1ed76be34bdb84 +Subproject commit 9939c2707cffbb8f2f15cfa79e80992cd58d6bdf diff --git a/src/app/topic/indicators.component.ts b/src/app/topic/indicators.component.ts index 779576e..07a1546 100644 --- a/src/app/topic/indicators.component.ts +++ b/src/app/topic/indicators.component.ts @@ -96,15 +96,17 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV @ViewChild('editNumberNotify', {static: true}) editNumberNotify: NotifyFormComponent; @ViewChild('editChartNotify', {static: true}) editChartNotify: NotifyFormComponent; @ViewChild('deleteNotify', {static: true}) deleteNotify: NotifyFormComponent; - - public isFullscreen: boolean = false; - @HostListener('fullscreenchange', ['$event']) - @HostListener('webkitfullscreenchange', ['$event']) - @HostListener('mozfullscreenchange', ['$event']) - @HostListener('MSFullscreenChange', ['$event']) - screenChange(event) { - this.isFullscreen = !this.isFullscreen; - } + + public isFullscreen: boolean = false; + + @HostListener('fullscreenchange', ['$event']) + @HostListener('webkitfullscreenchange', ['$event']) + @HostListener('mozfullscreenchange', ['$event']) + @HostListener('MSFullscreenChange', ['$event']) + screenChange(event) { + this.isFullscreen = !this.isFullscreen; + } + /** * Subscriptions **/ @@ -280,7 +282,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV urls.forEach((indexes, pair) => { let parsed = JSON.parse(pair); let response = this.numberResponses.get(pair); - if(response) { + if (response) { this.calculateResults(response, indexes); } else { this.numberSubscription.push(this.statisticsService.getNumbers(this.statisticsService.getSourceType(parsed[0]), parsed[1]).subscribe(response => { @@ -680,7 +682,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.notification = NotificationUtils.editIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); this.editNumberNotify.reset(this.notification.message); } - this.editNumberModal.stayOpen = true; + this.editNumberModal.stayOpen = true; this.editNumberModal.open(); } @@ -747,7 +749,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV ; this.editChartNotify.reset(this.notification.message); } - this.editChartModal.stayOpen = true; + this.editChartModal.stayOpen = true; this.editChartModal.open(); } @@ -811,12 +813,12 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - if(this.indicator.type === "chart") { - this.editChartModal.cancel(); - } else { - this.editNumberModal.cancel(); - } + this.editing = false; + if (this.indicator.type === "chart") { + this.editChartModal.cancel(); + } else { + this.editNumberModal.cancel(); + } }, error => { this.chartIndicatorFb = null; UIkit.notification(error.error.message, { @@ -824,12 +826,12 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV timeout: 6000, pos: 'bottom-right' }); - this.editing = false; - if(this.indicator.type === "chart") { - this.editChartModal.cancel(); - } else { - this.editNumberModal.cancel(); - } + this.editing = false; + if (this.indicator.type === "chart") { + this.editChartModal.cancel(); + } else { + this.editNumberModal.cancel(); + } })); } @@ -886,7 +888,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV NotificationHandler.rise('Indicators have been imported successfully!'); }, error => { this.chartIndicatorFb = null; - NotificationHandler.rise(error.error.message, 'danger'); + NotificationHandler.rise('An error has occurred. Please try again later', 'danger'); this.editing = false; this.importLoading = false; })); @@ -962,7 +964,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.deleteModal.okButtonText = 'Yes'; this.notification = NotificationUtils.deleteIndicator(this.user.firstname + ' ' + this.user.lastname, this.stakeholder.name); this.deleteNotify.reset(this.notification.message); - this.deleteModal.stayOpen = true; + this.deleteModal.stayOpen = true; this.deleteModal.open(); } @@ -1005,7 +1007,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV }); } this.editing = false; - this.deleteModal.cancel(); + this.deleteModal.cancel(); }, error => { UIkit.notification(error.error.message, { status: 'danger', @@ -1013,7 +1015,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV pos: 'bottom-right' }); this.editing = false; - this.deleteModal.cancel(); + this.deleteModal.cancel(); })); } @@ -1046,7 +1048,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV } saveSection(focused: boolean, sectionControl: AbstractControl, index: number, type: IndicatorType = "chart") { - if(!focused && sectionControl.dirty) { + if (!focused && sectionControl.dirty) { this.editing = true; let path = [ this.stakeholder._id, @@ -1155,7 +1157,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.deleteSectionModal.alertTitle = 'Delete Section'; this.deleteSectionModal.cancelButtonText = 'No'; this.deleteSectionModal.okButtonText = 'Yes'; - this.deleteSectionModal.stayOpen = true; + this.deleteSectionModal.stayOpen = true; this.deleteSectionModal.open(); } } @@ -1184,7 +1186,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV pos: 'bottom-right' }); this.editing = false; - this.deleteSectionModal.cancel(); + this.deleteSectionModal.cancel(); }, error => { UIkit.notification(error.error.message, { status: 'danger', @@ -1192,89 +1194,105 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV pos: 'bottom-right' }); this.editing = false; - this.deleteSectionModal.cancel(); + this.deleteSectionModal.cancel(); })); } private checkForSchemaEnhancements(url: string) { this.showCheckForSchemaEnhancements = this.isAdministrator && url && !this.properties.useOldStatisticsSchema && this.indicatorUtils.checkForSchemaEnhancements(url); } + migrateFromOldImportJsonFile(charts){ + // first section contains numbers + // second contains charts + let hasNumbers = false; + for (let chart of charts) { + if (chart['type'] == 'number') { + hasNumbers = true; + break; + } + } + let chartsSection = (hasNumbers?1:0); // no numbers: first sections contains charts + for (let chart of charts) { + if (chart['sectionIndex'] == null) { + chart['sectionIndex'] = chart['type'] == 'chart' ? chartsSection : 0; + } + } + return charts; + } - importIndicatorsAndSave(charts: any[]) { + importIndicatorsAndSave(charts: any[]) { let sectionsToSave: Section[] = []; let countIndicators = 0; // name description additionalDescription, height, width, visibility let noValidParams = 0; let duplicates = 0; - for (let chart of charts) { - if(!chart['sectionIndex']){ - chart['sectionIndex'] = chart['type'] == 'chart'?1:0; - } - if(!sectionsToSave[chart['sectionIndex']]){ - let sectionToSave = new Section(chart['sectionType']?chart['sectionType']:chart['type'], chart['sectionTitle']); - sectionToSave.indicators = []; - sectionsToSave[chart['sectionIndex']] = sectionToSave; - } - let exists = false; - let indicatorPath; - // validate indicators' schema from file - let invalid_file_message = ""; - if (!chart.type) { - invalid_file_message = "No indicator type is specified. Type should be chart or number."; - } else if (chart.type != "chart" && chart.type != "number") { - invalid_file_message = "Invalid indicator type. Type should be chart or number."; - } else if (chart.type == "number" && !chart.jsonPath) { - invalid_file_message = "No jsonPath is specified for number indicator." - } else if (!chart.url) { - invalid_file_message = "No indicator url is specified."; - } - - if (invalid_file_message) { - UIkit.notification(invalid_file_message, { - status: 'danger', - timeout: 6000, - pos: 'bottom-right' - }); - this.editing = false; - this.importLoading = false; - break; - } - - if (chart.type == "chart") { - indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } - } else if (chart.type == "number") { - indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(chart.url), chart.url, this.stakeholder, - chart.jsonPath, this.statisticsService.numberSources.get(this.statisticsService.getNumberSource(chart.url))); - for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { - for (let chart of section.indicators) { - if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { - duplicates++; - exists = true; - } - } - - } - } - if (!this.isStakeholderParametersValid(indicatorPath)) { - noValidParams++; - } - if (!exists) { - let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, "RESTRICTED", [indicatorPath]); - sectionsToSave[chart['sectionIndex']].indicators.push(i); - countIndicators ++ ; - } - + charts = this.migrateFromOldImportJsonFile(charts); + for (let chart of charts) { + if (!sectionsToSave[chart['sectionIndex']]) { + let sectionToSave = new Section(chart['sectionType'] ? chart['sectionType'] : chart['type'], chart['sectionTitle']); + sectionToSave.indicators = []; + sectionsToSave[chart['sectionIndex']] = sectionToSave; } - + let exists = false; + let indicatorPath; + // validate indicators' schema from file + let invalid_file_message; + if (!chart.type) { + invalid_file_message = "No indicator type is specified. Type should be chart or number."; + } else if (chart.type != "chart" && chart.type != "number") { + invalid_file_message = "Invalid indicator type. Type should be chart or number."; + } else if (chart.type == "number" && !chart.jsonPath) { + invalid_file_message = "No jsonPath is specified for number indicator." + } else if (!chart.url) { + invalid_file_message = "No indicator url is specified."; + } + + if (invalid_file_message) { + UIkit.notification(invalid_file_message, { + status: 'danger', + timeout: 6000, + pos: 'bottom-right' + }); + this.editing = false; + this.importLoading = false; + break; + } + + if (chart.type == "chart") { + indicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(chart.url), chart.url, chart.type, this.stakeholder); + for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].charts) { + for (let chart of section.indicators) { + if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { + duplicates++; + exists = true; + } + } + + } + } else if (chart.type == "number") { + indicatorPath = this.indicatorUtils.generateIndicatorByNumberUrl(this.statisticsService.getNumberSource(chart.url), chart.url, this.stakeholder, + chart.jsonPath, this.statisticsService.numberSources.get(this.statisticsService.getNumberSource(chart.url))); + for (let section of this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.index].numbers) { + for (let chart of section.indicators) { + if (JSON.stringify(chart.indicatorPaths[0].chartObject) == JSON.stringify(indicatorPath.chartObject)) { + duplicates++; + exists = true; + } + } + + } + } + if (!this.isStakeholderParametersValid(indicatorPath)) { + noValidParams++; + } + if (!exists) { + let i: Indicator = new Indicator(chart.name, chart.description, chart.additionalDescription, chart.type, chart.width, chart.height, "RESTRICTED", [indicatorPath]); + sectionsToSave[chart['sectionIndex']].indicators.push(i); + countIndicators++; + } + + } + if (duplicates > 0) { UIkit.notification(duplicates + " urls already exist and will not be imported!", { status: 'warning', @@ -1294,7 +1312,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV }); this.editing = false; this.importLoading = false; - } else if (sectionsToSave.length > 0 && countIndicators >0) { + } else if (sectionsToSave.length > 0 && countIndicators > 0) { this.saveIndicators(sectionsToSave) } if (sectionsToSave.length == 0 || countIndicators == 0) { @@ -1316,21 +1334,21 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].numbers.forEach(section => { section.indicators.forEach(indicator => { indicator.indicatorPaths.forEach(indicatorPath => { - indicators[indexIndicator] = { + indicators[indexIndicator] = { "type": indicator.type, "name": indicator.name, "jsonPath": indicatorPath.jsonPath, "description": indicator.description, "additionalDescription": indicator.additionalDescription, "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, "url": this.statisticsService.getNumberUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath)), - "sectionTitle" : section.title, + "sectionTitle": section.title, "sectionType": section.type, "sectionIndex": index }; indexIndicator++; }); }); - index ++ ; - }); - + index++; + }); + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[subcategoryIndex].charts.forEach(section => { section.indicators.forEach(indicator => { indicator.indicatorPaths.forEach(indicatorPath => { @@ -1339,15 +1357,15 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV "description": indicator.description, "additionalDescription": indicator.additionalDescription, "visibility": indicator.visibility, "width": indicator.width, "height": indicator.height, "url": this.getUrlByStakeHolder(indicatorPath), - "sectionTitle" : section.title, - "sectionType": section.type, - "sectionIndex": index + "sectionTitle": section.title, + "sectionType": section.type, + "sectionIndex": index }; indexIndicator++; }); }); - index ++ ; - + index++; + }); let topic = this.stakeholder ? this.stakeholder.topics[this.topicIndex] : null; @@ -1448,20 +1466,20 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV xhr.send(formData); }); } - - copyToClipboard(value) { - const tempBox = document.createElement('textarea'); - tempBox.style.position = 'fixed'; - tempBox.style.left = '0'; - tempBox.style.top = '0'; - tempBox.style.opacity = '0'; - tempBox.value = value; - document.body.appendChild(tempBox); - tempBox.focus(); - tempBox.select(); - tempBox.setSelectionRange(0,99999); - document.execCommand('copy'); - document.body.removeChild(tempBox); + + copyToClipboard(value) { + const tempBox = document.createElement('textarea'); + tempBox.style.position = 'fixed'; + tempBox.style.left = '0'; + tempBox.style.top = '0'; + tempBox.style.opacity = '0'; + tempBox.value = value; + document.body.appendChild(tempBox); + tempBox.focus(); + tempBox.select(); + tempBox.setSelectionRange(0, 99999); + document.execCommand('copy'); + document.body.removeChild(tempBox); NotificationHandler.rise('Copied to clipboard'); - } + } }