diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8de29aa..a447fe6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -60,6 +60,7 @@ export class AppComponent implements OnInit, OnDestroy { this.hasAdminMenu = hasAdminMenu; this.cdr.detectChanges(); })); + this.layoutService.setOpen(false); this.propertiesService.loadEnvironment() .then(properties => { this.properties = properties; diff --git a/src/app/manageStakeholders/manageStakeholders.component.ts b/src/app/manageStakeholders/manageStakeholders.component.ts index 70875e6..d811e2b 100644 --- a/src/app/manageStakeholders/manageStakeholders.component.ts +++ b/src/app/manageStakeholders/manageStakeholders.component.ts @@ -12,251 +12,250 @@ import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sideb import {Option} from "../openaireLibrary/dashboard/sharedComponents/input/input.component"; @Component({ - selector: 'home', - templateUrl: "./manageStakeholders.component.html" + selector: 'home', + templateUrl: "./manageStakeholders.component.html" }) export class ManageStakeholdersComponent implements OnInit, OnDestroy { - - public properties: EnvProperties; - public loading: boolean = true; - public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); - public defaultStakeholders: Stakeholder[]; - public stakeholders: Stakeholder[]; - public stakeholder: Stakeholder; - public stakeholderFb: FormGroup; - public index: number; - - /** - * Filtered Stakeholders - */ - public displayDefaultStakeholders: Stakeholder[]; - public displayStakeholders: Stakeholder[]; - - /** - * Top filters - */ - public filters: FormGroup; - public all: Option = { - value: 'all', - label: 'All' - }; - - /** - * Grid or List View - */ - public grid: boolean = true; - private subscriptions: any[] = []; - - @ViewChild('editStakeholderModal') editStakeholderModal: AlertModal; - @ViewChild('deleteStakeholderModal') deleteStakeholderModal: AlertModal; - - constructor(private stakeholderService: StakeholderService, - private propertiesService: EnvironmentSpecificService, - private fb: FormBuilder, private layoutService: LayoutService) { - } - - ngOnInit(): void { - this.buildFilters(); - this.propertiesService.loadEnvironment() - .then(properties => { - this.properties = properties; - let data = zip( - this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL), - this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL) - ); - data.subscribe(res => { - this.defaultStakeholders = res[0]; - this.stakeholders = res[1]; - this.displayDefaultStakeholders = res[0]; - this.displayStakeholders = res[1]; - this.loading = false; - }); - }); - this.layoutService.setHasHeader(true); - this.layoutService.setOpen(true); - } - - ngOnDestroy(): void { - this.subscriptions.forEach(value => { - if (value instanceof Subscriber) { - value.unsubscribe(); - } + + public properties: EnvProperties; + public loading: boolean = true; + public stakeholderUtils: StakeholderUtils = new StakeholderUtils(); + public defaultStakeholders: Stakeholder[]; + public stakeholders: Stakeholder[]; + public stakeholder: Stakeholder; + public stakeholderFb: FormGroup; + public index: number; + + /** + * Filtered Stakeholders + */ + public displayDefaultStakeholders: Stakeholder[]; + public displayStakeholders: Stakeholder[]; + + /** + * Top filters + */ + public filters: FormGroup; + public all: Option = { + value: 'all', + label: 'All' + }; + + /** + * Grid or List View + */ + public grid: boolean = true; + private subscriptions: any[] = []; + + @ViewChild('editStakeholderModal') editStakeholderModal: AlertModal; + @ViewChild('deleteStakeholderModal') deleteStakeholderModal: AlertModal; + + constructor(private stakeholderService: StakeholderService, + private propertiesService: EnvironmentSpecificService, + private fb: FormBuilder) { + } + + ngOnInit(): void { + this.buildFilters(); + this.propertiesService.loadEnvironment() + .then(properties => { + this.properties = properties; + let data = zip( + this.stakeholderService.getDefaultStakeholders(this.properties.monitorServiceAPIURL), + this.stakeholderService.getStakeholders(this.properties.monitorServiceAPIURL) + ); + data.subscribe(res => { + this.defaultStakeholders = res[0]; + this.stakeholders = res[1]; + this.displayDefaultStakeholders = res[0]; + this.displayStakeholders = res[1]; + this.loading = false; }); + }); + } + + ngOnDestroy(): void { + this.subscriptions.forEach(value => { + if (value instanceof Subscriber) { + value.unsubscribe(); + } + }); + } + + public changeGrid(value) { + this.grid = value; + } + + private buildFilters() { + this.filters = this.fb.group({ + privacy: this.fb.control('all'), + status: this.fb.control('all'), + keyword: this.fb.control('') + }); + this.subscriptions.push(this.filters.get('privacy').valueChanges.subscribe(value => { + this.onPrivacyChange(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); + })); + } + + onPrivacyChange(value) { + this.displayDefaultStakeholders = this.filterPrivacy(this.defaultStakeholders, value); + this.displayStakeholders = this.filterPrivacy(this.stakeholders, value); + } + + onStatusChange(value) { + this.displayDefaultStakeholders = this.filterStatus(this.defaultStakeholders, value); + this.displayStakeholders = this.filterStatus(this.stakeholders, value); + } + + onKeywordChange(value) { + this.displayDefaultStakeholders = this.filterByKeyword(this.defaultStakeholders, value); + this.displayStakeholders = this.filterByKeyword(this.stakeholders, value); + } + + + private filterPrivacy(stakeholders: Stakeholder[], value): Stakeholder[] { + if (value === 'all') { + return stakeholders; + } else { + return stakeholders.filter(stakeholder => stakeholder.isPublic === value); } - - public changeGrid(value) { - this.grid = value; + } + + private filterStatus(stakeholders: Stakeholder[], value): Stakeholder[] { + if (value === 'all') { + return stakeholders; + } else { + return stakeholders.filter(stakeholder => stakeholder.isActive === value); } - - private buildFilters() { - this.filters = this.fb.group({ - privacy: this.fb.control('all'), - status: this.fb.control('all'), - keyword: this.fb.control('') - }); - this.subscriptions.push(this.filters.get('privacy').valueChanges.subscribe(value => { - this.onPrivacyChange(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 filterByKeyword(stakeholders: Stakeholder[], value): Stakeholder[] { + if (value === null || value === '') { + return stakeholders; + } else { + return stakeholders.filter(stakeholder => ( + stakeholder.index_id && stakeholder.index_id.toLowerCase().includes(value.toLowerCase())) || + stakeholder.index_shortName && stakeholder.index_shortName.toLowerCase().includes(value.toLowerCase()) || + stakeholder.index_name && stakeholder.index_name.toLowerCase().includes(value.toLowerCase()) + ); } - - onPrivacyChange(value) { - this.displayDefaultStakeholders = this.filterPrivacy(this.defaultStakeholders, value); - this.displayStakeholders = this.filterPrivacy(this.stakeholders, value); + } + + public editStakeholder(stakeholder: Stakeholder = null, isDefault: boolean = false) { + if (isDefault) { + this.index = (stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === stakeholder._id) : -1; + } else { + this.index = (stakeholder) ? this.stakeholders.findIndex(value => value._id === stakeholder._id) : -1; } - - onStatusChange(value) { - this.displayDefaultStakeholders = this.filterStatus(this.defaultStakeholders, value); - this.displayStakeholders = this.filterStatus(this.stakeholders, value); + if (!stakeholder) { + this.stakeholder = new Stakeholder(null, null, null, + null, null, null, false, false, null); + } else { + this.stakeholder = stakeholder; } - - onKeywordChange(value) { - this.displayDefaultStakeholders = this.filterByKeyword(this.defaultStakeholders, value); - this.displayStakeholders = this.filterByKeyword(this.stakeholders, value); + this.stakeholderFb = this.fb.group({ + _id: this.fb.control(this.stakeholder._id), + index_name: this.fb.control(this.stakeholder.index_name, Validators.required), + index_id: this.fb.control(this.stakeholder.index_id, Validators.required), + index_shortName: this.fb.control(this.stakeholder.index_shortName, Validators.required), + defaultId: this.fb.control((isDefault) ? null : 'id'), + creationDate: this.fb.control(this.stakeholder.creationDate), + alias: this.fb.control(this.stakeholder.alias, + [ + Validators.required, + this.stakeholderUtils.aliasValidator( + (isDefault) ? + this.defaultStakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias) : + this.stakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias) + )] + ), + isPublic: this.fb.control(this.stakeholder.isPublic), + isActive: this.fb.control(this.stakeholder.isActive), + type: this.fb.control(this.stakeholder.type, Validators.required), + topics: this.fb.control(this.stakeholder.topics), + managers: this.fb.control(this.stakeholder.managers), + logoUrl: this.fb.control(this.stakeholder.logoUrl) + }); + if (this.index !== -1) { + if (this.stakeholderFb.value.type) { + setTimeout(() => { + this.stakeholderFb.get('type').disable(); + }, 0); + } else { + setTimeout(() => { + this.stakeholderFb.get('type').enable(); + }, 0); + } + this.editStakeholderModal.okButtonText = 'Save Changes'; + } else { + setTimeout(() => { + this.stakeholderFb.get('type').enable(); + }, 0); + this.editStakeholderModal.okButtonText = 'Create'; } - - - private filterPrivacy(stakeholders: Stakeholder[], value): Stakeholder[] { - if (value === 'all') { - return stakeholders; - } else { - return stakeholders.filter(stakeholder => stakeholder.isPublic === value); - } - } - - private filterStatus(stakeholders: Stakeholder[], value): Stakeholder[] { - if (value === 'all') { - return stakeholders; - } else { - return stakeholders.filter(stakeholder => stakeholder.isActive === value); - } - } - - private filterByKeyword(stakeholders: Stakeholder[], value): Stakeholder[] { - if (value === null || value === '') { - return stakeholders; - } else { - return stakeholders.filter(stakeholder => ( - stakeholder.index_id && stakeholder.index_id.toLowerCase().includes(value.toLowerCase())) || - stakeholder.index_shortName && stakeholder.index_shortName.toLowerCase().includes(value.toLowerCase()) || - stakeholder.index_name && stakeholder.index_name.toLowerCase().includes(value.toLowerCase()) - ); - } - } - - public editStakeholder(stakeholder: Stakeholder = null, isDefault: boolean = false) { - if (isDefault) { - this.index = (stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === stakeholder._id) : -1; - } else { - this.index = (stakeholder) ? this.stakeholders.findIndex(value => value._id === stakeholder._id) : -1; - } - if (!stakeholder) { - this.stakeholder = new Stakeholder(null, null, null, - null, null, isDefault, null, false, false, null); - } else { - this.stakeholder = stakeholder; - } - this.stakeholderFb = this.fb.group({ - _id: this.fb.control(this.stakeholder._id), - index_name: this.fb.control(this.stakeholder.index_name, Validators.required), - 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), - creationDate: this.fb.control(this.stakeholder.creationDate), - alias: this.fb.control(this.stakeholder.alias, - [ - Validators.required, - this.stakeholderUtils.aliasValidator( - (this.stakeholder.isDefaultProfile) ? - this.defaultStakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias): - this.stakeholders.filter(stakeholder => stakeholder.alias !== this.stakeholder.alias) - )] - ), - isPublic: this.fb.control(this.stakeholder.isPublic), - isActive: this.fb.control(this.stakeholder.isActive), - type: this.fb.control(this.stakeholder.type, Validators.required), - topics: this.fb.control(this.stakeholder.topics), - managers: this.fb.control(this.stakeholder.managers), - logoUrl: this.fb.control(this.stakeholder.logoUrl) - }); - if (this.index !== -1) { - if (this.stakeholderFb.value.type) { - setTimeout(() => { - this.stakeholderFb.get('type').disable(); - }, 0); - } else { - setTimeout(() => { - this.stakeholderFb.get('type').enable(); - }, 0); - } - this.editStakeholderModal.okButtonText = 'Save Changes'; - } else { - setTimeout(() => { - this.stakeholderFb.get('type').enable(); - }, 0); - this.editStakeholderModal.okButtonText = 'Create'; - } - this.editStakeholderModal.cancelButtonText = 'Cancel'; - this.editStakeholderModal.okButtonLeft = false; - this.editStakeholderModal.alertMessage = false; - this.editStakeholderModal.open(); - } - - public saveStakeholder() { - if (this.index === -1) { - 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)); - this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.value, StakeholderCreator.createFunderDefaultProfile().topics)); - }/* else { + this.editStakeholderModal.cancelButtonText = 'Cancel'; + this.editStakeholderModal.okButtonLeft = false; + this.editStakeholderModal.alertMessage = false; + this.editStakeholderModal.open(); + } + + public saveStakeholder() { + if (this.index === -1) { + if (this.stakeholderFb.value.defaultId) { + // TODO set defaultId from default profile + // this.stakeholderFb.setValue(this.stakeholderUtils. + // createFunderFromDefaultProfile(this.stakeholderFb.value, + // this.defaultStakeholders.find( value => value.type === this.stakeholderFb.value.type).topics)); + this.stakeholderFb.setValue(this.stakeholderUtils.createFunderFromDefaultProfile(this.stakeholderFb.value, StakeholderCreator.createFunderDefaultProfile().topics)); + }/* else { this.stakeholderFb.setValue(StakeholderCreator.createFunderDefaultProfile()); }*/ - this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).subscribe(stakeholder => { - if (stakeholder.isDefaultProfile) { - this.defaultStakeholders.push(stakeholder); - } else { - this.stakeholders.push(stakeholder); - } - }); + this.stakeholderService.buildStakeholder(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).subscribe(stakeholder => { + if (stakeholder.defaultId === null) { + this.defaultStakeholders.push(stakeholder); } else { - this.stakeholderFb.get('type').enable(); - this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).subscribe(stakeholder => { - if (stakeholder.isDefaultProfile) { - this.defaultStakeholders[this.index] = stakeholder; - } else { - this.stakeholders[this.index] = stakeholder; - } - }); + this.stakeholders.push(stakeholder); } - } - - public deleteStakeholderOpen(stakeholder: Stakeholder) { - this.stakeholder = stakeholder; - this.deleteStakeholderModal.alertTitle = 'Delete ' + this.stakeholder.index_name; - this.deleteStakeholderModal.cancelButtonText = 'No'; - this.deleteStakeholderModal.okButtonText = 'Yes'; - this.deleteStakeholderModal.message = 'This stakeholder will permanently be deleted. Are you sure you want to proceed?'; - this.deleteStakeholderModal.open(); - } - - public deleteStakeholder() { - if (this.stakeholder.isDefaultProfile) { - this.index = (this.stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === this.stakeholder._id) : -1; + }); + } else { + this.stakeholderFb.get('type').enable(); + this.stakeholderService.saveElement(this.properties.monitorServiceAPIURL, this.stakeholderFb.value).subscribe(stakeholder => { + if (stakeholder.isDefaultProfile) { + this.defaultStakeholders[this.index] = stakeholder; } else { - this.index = (this.stakeholder) ? this.stakeholders.findIndex(value => value._id === this.stakeholder._id) : -1; + this.stakeholders[this.index] = stakeholder; } - this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, [this.stakeholder._id]).subscribe(() => { - if (this.stakeholder.isDefaultProfile) { - this.defaultStakeholders.splice(this.index, 1); - } else { - this.stakeholders.splice(this.index, 1); - } - }); + }); } + } + + public deleteStakeholderOpen(stakeholder: Stakeholder) { + this.stakeholder = stakeholder; + this.deleteStakeholderModal.alertTitle = 'Delete ' + this.stakeholder.index_name; + this.deleteStakeholderModal.cancelButtonText = 'No'; + this.deleteStakeholderModal.okButtonText = 'Yes'; + this.deleteStakeholderModal.message = 'This stakeholder will permanently be deleted. Are you sure you want to proceed?'; + this.deleteStakeholderModal.open(); + } + + public deleteStakeholder() { + if (!this.stakeholder.defaultId) { + this.index = (this.stakeholder) ? this.defaultStakeholders.findIndex(value => value._id === this.stakeholder._id) : -1; + } else { + this.index = (this.stakeholder) ? this.stakeholders.findIndex(value => value._id === this.stakeholder._id) : -1; + } + this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, [this.stakeholder._id]).subscribe(() => { + if (!this.stakeholder.defaultId) { + this.defaultStakeholders.splice(this.index, 1); + } else { + this.stakeholders.splice(this.index, 1); + } + }); + } } diff --git a/src/app/monitor/monitor.component.html b/src/app/monitor/monitor.component.html index fb350c7..8adadb4 100644 --- a/src/app/monitor/monitor.component.html +++ b/src/app/monitor/monitor.component.html @@ -39,7 +39,8 @@ @@ -57,9 +58,6 @@
Monitor Dashboard
- - -
--> - - -
+
No indicators available yet. Stay tuned!
-
- +
-
-
-
- {{number.name}} -

- {{numberResults.get(i) | number}} -

+

{{number.title}}

+ +
+
+
+ {{indicator.name}} +

+ {{numberResults.get(i + '-' + j) | number}} +

+
-
+
-
-
- -

-
{{chart.name + " "}}
-

-
-
-
- +

{{chart.title}}

+ +
+
+

+
{{indicator.name + " "}}
+

+
+
+
+ +
+ + + +
- - - -
-
+
diff --git a/src/app/monitor/monitor.component.ts b/src/app/monitor/monitor.component.ts index ef63787..7faf801 100644 --- a/src/app/monitor/monitor.component.ts +++ b/src/app/monitor/monitor.component.ts @@ -45,11 +45,11 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent public activeTopic: Topic = null; public activeCategory: Category = null; public activeSubCategory: SubCategory = null; - public sideBarItems:MenuItem[] = []; + public sideBarItems: MenuItem[] = []; public errorCodes: ErrorCodes; public stakeholder: Stakeholder; - public numberResults: Map = new Map(); - public chartsActiveType: Map = new Map(); + public numberResults: Map = new Map(); + public chartsActiveType: Map = new Map(); private errorMessages: ErrorMessagesComponent; properties: EnvProperties; fundingL0; @@ -94,25 +94,24 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent var url = data.envSpecific.baseLink + this._router.url; if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder']) { this.status = this.errorCodes.LOADING; - this.numberResults = new Map(); - this.chartsActiveType = new Map(); + this.numberResults = new Map(); + this.chartsActiveType = new Map(); // subscription = 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); + "fwf", true, true, null); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder.logoUrl = "./assets/fwf.png"; } else if (params['stakeholder'] == "arc") { stakeholder = new Stakeholder(null, "funder", "arc_________::ARC", - "Australian Research Council (ARC)", "ARC", - false, null, true, true, null); + "Australian Research Council (ARC)", "ARC", "arc", true, true, null); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder.logoUrl = "./assets/arc1.gif"; } else { stakeholder = new Stakeholder(null, "funder", "ec__________::EC", "European Commission", "EC", - false, "ec", true, true, null); + "ec", true, true, null); stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); stakeholder.logoUrl = "./assets/ec.png"; } @@ -133,6 +132,7 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent this.getPageContents(); this.status = this.errorCodes.DONE; this.setView(params); + this.layoutService.setOpen(true); } // }, error => { // this.navigateToError(); @@ -149,75 +149,6 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent console.log(error); })); }); - this.route.data - .subscribe((data: { envSpecific: EnvProperties }) => { - let subscription: Subscription; - this.route.params.subscribe(params => { - if(subscription) { - subscription.unsubscribe(); - } - this.properties = data.envSpecific; - var url = data.envSpecific.baseLink + this._router.url; - if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder']) { - this.status = this.errorCodes.LOADING; - this.numberResults = new Map(); - this.chartsActiveType = new Map(); - // subscription = 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); - stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); - stakeholder.logoUrl = "./assets/fwf.png"; - } else if (params['stakeholder'] == "arc") { - stakeholder = new Stakeholder(null, "funder", "arc_________::ARC", - "Australian Research Council (ARC)", "ARC", - false, "arc", true, true, null); - stakeholder = this.stakeholderUtils.createFunderFromDefaultProfile(stakeholder, StakeholderCreator.createFunderDefaultProfile().topics); - stakeholder.logoUrl = "./assets/arc1.gif"; - } else { - stakeholder = new Stakeholder(null, "funder", "ec__________::EC", - "European Commission", "EC", - 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); - this._meta.updateTag({content: url}, "property='og:url'"); - var description = "Monitor Dashboard | " + this.stakeholder.index_name; - var title = "Monitor Dashboard | " + this.stakeholder.index_shortName; - this._meta.updateTag({content: description}, "name='description'"); - this._meta.updateTag({content: description}, "property='og:description'"); - this._meta.updateTag({content: title}, "property='og:title'"); - this._title.setTitle(title); - if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) { - this.piwiksub = this._piwikService.trackView(this.properties, title, this.properties.piwikSiteId).subscribe(); - } - //this.getDivContents(); - this.getPageContents(); - this.status = this.errorCodes.DONE; - this.setView(params); - this.layoutService.setOpen(true); - } - // }, error => { - // this.navigateToError(); - // }); - this.subscriptions.push(subscription); - } else { - this.setView(params); - } - this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => { - this.user = user; - this.buildMenu(); - }, error => { - console.log("App couldn't fetch properties"); - console.log(error); - })); - }); - }); - }); } @@ -338,9 +269,9 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent let subItems: MenuItem[] = []; category.subCategories.forEach(subCategory => { if (subCategory.isPublic && subCategory.isActive) { - subItems.push(new MenuItem(subCategory.alias, subCategory.name,"", ( + subItems.push(new MenuItem(subCategory.alias, subCategory.name, "", ( '/' + this.stakeholder.alias + '/' + this.activeTopic.alias + '/' + category.alias + '/' + subCategory.alias), - null, null, [],{})); + null, null, [], {})); } }); let open = this.activeCategory.alias === category.alias; @@ -348,54 +279,58 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent open = MonitorComponent.sidebarStatus.status[index]; } // constructor(id: string, title: string, url: string, route: string, needsAuthorization: boolean, entitiesRequired: string[], routeRequired: string[], params) { - let categoryItem:MenuItem = new MenuItem(category.alias, category.name,"", ( + let categoryItem: MenuItem = new MenuItem(category.alias, category.name, "", ( '/' + this.stakeholder.alias + '/' + this.activeTopic.alias + '/' + category.alias), - null, [],[],{}); + null, [], [], {}); categoryItem.items = subItems; categoryItem.open = open; items.push(categoryItem); } }); if (items.length === 0) { - items.push(new MenuItem('noCategories', 'No categories available yet', "", "",false,[], [], {})); + items.push(new MenuItem('noCategories', 'No categories available yet', "", "", false, [], [], {})); } this.sideBarItems = items; } private setIndicators() { - let urls: Map = new Map(); - this.activeSubCategory.numbers.forEach((number, index) => { - if (number.isActive && number.isPublic) { - let url = number.indicatorPaths[0].url; - //add fundingLevel0 filter in the query - if (this.fundingL0 && number.indicatorPaths[0].filters.get("fundingL0")) { - url = url + number.indicatorPaths[0].filters.get("fundingL0").replace(ChartHelper.prefix + 'fundingL0' + ChartHelper.suffix, encodeURIComponent(this.fundingL0)); + let urls: Map = new Map(); + this.activeSubCategory.numbers.forEach((section, i) => { + section.indicators.forEach((number, j) => { + if (number.isActive && number.isPublic) { + let url = number.indicatorPaths[0].url; + //add fundingLevel0 filter in the query + if (this.fundingL0 && number.indicatorPaths[0].filters.get("fundingL0")) { + url = url + number.indicatorPaths[0].filters.get("fundingL0").replace(ChartHelper.prefix + 'fundingL0' + ChartHelper.suffix, encodeURIComponent(this.fundingL0)); + } + 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); } - const pair = JSON.stringify([number.indicatorPaths[0].source, url]); - const indexes = urls.get(pair) ? urls.get(pair) : []; - indexes.push(index); - urls.set(pair, indexes); - } + }); }); urls.forEach((indexes, pair) => { pair = JSON.parse(pair); this.statisticsService.getNumbers(pair[0], pair[1]).subscribe(response => { - indexes.forEach(index => { + indexes.forEach(([i, j]) => { let result = JSON.parse(JSON.stringify(response)); - this.activeSubCategory.numbers[index].indicatorPaths[0].jsonPath.forEach(jsonPath => { + this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => { if (result) { result = result[jsonPath]; } }); - this.numberResults.set(index, result); + this.numberResults.set(i + '-' + j, result); }); }) }); - this.activeSubCategory.charts.forEach((chart, index) => { - if (chart.indicatorPaths.length > 0) { - chart.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(chart.indicatorPaths[0]); - this.chartsActiveType.set(index, chart.indicatorPaths[0]); - } + this.activeSubCategory.charts.forEach((section, i) => { + section.indicators.forEach((indicator, j) => { + if (indicator.indicatorPaths.length > 0) { + indicator.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[0]); + this.chartsActiveType.set(i + '-' + j, indicator.indicatorPaths[0]); + } + }); }); this.cdr.detectChanges(); } @@ -405,10 +340,10 @@ export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(indicatorPath, this.fundingL0, this.startYear, this.endYear))); } - public setActiveChart(index, type: string) { - let activeChart = this.activeSubCategory.charts[index].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0]; + public setActiveChart(i: number, j: number, type: string) { + let activeChart = this.activeSubCategory.charts[i].indicators[j].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0]; activeChart.safeResourceUrl = this.getUrlByStakeHolder(activeChart); - this.chartsActiveType.set(index, activeChart); + this.chartsActiveType.set(i + '-' + j, activeChart); } private navigateToError() { diff --git a/src/app/stakeholder/stakeholder-routing.module.ts b/src/app/stakeholder/stakeholder-routing.module.ts index 0244563..285d7c9 100644 --- a/src/app/stakeholder/stakeholder-routing.module.ts +++ b/src/app/stakeholder/stakeholder-routing.module.ts @@ -3,6 +3,7 @@ import {RouterModule} from '@angular/router'; import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard'; import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard'; import {StakeholderComponent} from "./stakeholder.component"; +import {CanExitGuard} from "../openaireLibrary/utils/can-exit.guard"; @NgModule({ imports: [ @@ -11,7 +12,7 @@ import {StakeholderComponent} from "./stakeholder.component"; path: '', component: StakeholderComponent, canActivate: [FreeGuard], - canDeactivate: [PreviousRouteRecorder] + canDeactivate: [PreviousRouteRecorder, CanExitGuard] } ]) ] diff --git a/src/app/stakeholder/stakeholder.component.ts b/src/app/stakeholder/stakeholder.component.ts index 0d8fd6b..4f8d3da 100644 --- a/src/app/stakeholder/stakeholder.component.ts +++ b/src/app/stakeholder/stakeholder.component.ts @@ -5,7 +5,7 @@ import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties' import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes'; import {ErrorMessagesComponent} from '../openaireLibrary/utils/errorMessages.component'; -import {Indicator, Stakeholder, Topic} from "../utils/entities/stakeholder"; +import {Stakeholder, Topic} from "../utils/entities/stakeholder"; import {StakeholderService} from "../services/stakeholder.service"; import {HelperFunctions} from "../openaireLibrary/utils/HelperFunctions.class"; import {AlertModal} from "../openaireLibrary/utils/modal/alert"; @@ -13,6 +13,7 @@ import {Subscriber} from "rxjs"; import {FormBuilder, FormGroup, Validators} from "@angular/forms"; import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service"; import {StakeholderUtils} from "../utils/indicator-utils"; +import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard"; declare var UIkit; @@ -20,7 +21,7 @@ declare var UIkit; selector: 'stakeholder', templateUrl: './stakeholder.component.html', }) -export class StakeholderComponent implements OnInit, OnDestroy { +export class StakeholderComponent implements OnInit, OnDestroy, IDeactivateComponent { public subscriptions: any[] = []; public loading: boolean = true; public errorCodes: ErrorCodes; @@ -61,11 +62,16 @@ export class StakeholderComponent implements OnInit, OnDestroy { } public ngOnDestroy() { + } + + canExit():boolean { this.subscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } }); + this.stakeholderService.setStakeholder(this.stakeholder); + return true; } get open(): boolean { @@ -93,7 +99,7 @@ export class StakeholderComponent implements OnInit, OnDestroy { ), isActive: this.fb.control(topic.isActive), isPublic: this.fb.control(topic.isPublic), - isDefault: this.fb.control(topic.isDefault), + defaultId: this.fb.control(topic.defaultId), categories: this.fb.control(topic.categories) }); this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { @@ -110,7 +116,7 @@ export class StakeholderComponent implements OnInit, OnDestroy { public editTopicOpen(index = -1) { this.index = index; if (index === -1) { - this.buildTopic(new Topic(null, null, null, true, true, false)); + this.buildTopic(new Topic(null, null, null, true, true)); } else { this.buildTopic(this.stakeholder.topics[index]); } @@ -153,7 +159,6 @@ export class StakeholderComponent implements OnInit, OnDestroy { } else { this.stakeholder.topics[index] = topic; } - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification(message, { status: 'success', timeout: 3000, @@ -175,7 +180,6 @@ export class StakeholderComponent implements OnInit, OnDestroy { ]; this.stakeholderService.deleteElement(this.properties.monitorServiceAPIURL, path).subscribe(() => { this.stakeholder.topics.splice(this.index, 1); - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification('Topic has been successfully deleted', { status: 'success', timeout: 3000, @@ -197,7 +201,6 @@ export class StakeholderComponent implements OnInit, OnDestroy { ]; this.stakeholderService.toggleStatus(this.properties.monitorServiceAPIURL, path).subscribe(isActive => { topic.isActive = isActive; - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification('Topic has been successfully ' + (isActive?'activated':'deactivated'), { status: 'success', timeout: 3000, @@ -219,7 +222,6 @@ export class StakeholderComponent implements OnInit, OnDestroy { ]; this.stakeholderService.toggleAccess(this.properties.monitorServiceAPIURL, path).subscribe(isPublic => { topic.isPublic = isPublic; - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification('Topic has been successfully changed to ' + (isPublic?'public':'private'), { status: 'success', timeout: 3000, diff --git a/src/app/topic/indicators.component.html b/src/app/topic/indicators.component.html index 44e302f..84f6118 100644 --- a/src/app/topic/indicators.component.html +++ b/src/app/topic/indicators.component.html @@ -51,15 +51,20 @@

Number Indicators

-
- + *ngFor="let number of displayNumbers; let i = index" + uk-sortable="group: number" uk-grid> +
+

{{number.title}}

+
+
-
+ [class.uk-width-1-1@m]="!grid || indicator.width === 'large'" + [class.uk-sortable-nodrag]="!canReorder"> +
- {{indicator.name?indicator.name:'No title available'}} + {{indicator.name ? indicator.name : 'No title available'}}
@@ -115,18 +120,23 @@

Chart Indicators

-
- -
-
-
-
- + +
+
+

{{chart.title}}

+
+ +
+
+
+
+ @@ -134,100 +144,101 @@ {{indicatorPath.type + ' Chart'}} - - + + {{indicatorUtils.isPublicIcon.get(indicator.isPublic)}} - {{(indicator.isPublic) ? 'Public' : 'Private'}} + {{(indicator.isPublic) ? 'Public' : 'Private'}} - + {{indicatorUtils.isActiveIcon}} - {{(indicator.isActive) ? 'Active' : 'Inactive'}} + {{(indicator.isActive) ? 'Active' : 'Inactive'}} -
- more_vert - +
+ {{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters['title']}} +
+
+
+
+
+ {{indicator.description ? indicator.description : ''}} +
+
+
+ + {{indicatorUtils.chartTypesIcons.get(indicatorPath.type)}} + +
{{indicatorPath.type + ' Chart'}}
+
+
+
+ + {{indicatorUtils.isPublicIcon.get(indicator.isPublic)}} + +
{{(indicator.isPublic) ? 'Public' : 'Private'}}
+
+
+ + {{indicatorUtils.isActiveIcon}} + +
{{(indicator.isActive) ? 'Active' : 'Inactive'}}
-
- {{indicator.name?indicator.name:indicator.indicatorPaths[0].parameters['title']}} +
+
+ +
+
+
+
+ add + Create a custom Indicator
-
+
- {{indicator.description ? indicator.description : ''}} + Use our advance tool to create a custom Indicator that suit the needs of your funding + KPI's.
-
-
- - {{indicatorUtils.chartTypesIcons.get(indicatorPath.type)}} - -
{{indicatorPath.type + ' Chart'}}
-
+
+ add
-
- - {{indicatorUtils.isPublicIcon.get(indicator.isPublic)}} - -
{{(indicator.isPublic) ? 'Public' : 'Private'}}
-
-
- - {{indicatorUtils.isActiveIcon}} - -
{{(indicator.isActive) ? 'Active' : 'Inactive'}}
-
-
-
-
-
- -
-
-
-
- add - Create a custom Indicator -
-
-
-
-
- Use our advance tool to create a custom Indicator that suit the needs of your funding - KPI's. -
-
- add
-
+
You are about to delete - "{{indicator.name?indicator.name:indicator.indicatorPaths[0].parameters.title}}" indicator permanently. + "{{indicator.name ? indicator.name : indicator.indicatorPaths[0].parameters.title}}" indicator permanently. Are you sure you want to proceed? diff --git a/src/app/topic/indicators.component.ts b/src/app/topic/indicators.component.ts index 3af0aa0..7384ebc 100644 --- a/src/app/topic/indicators.component.ts +++ b/src/app/topic/indicators.component.ts @@ -1,5 +1,5 @@ import {AfterViewInit, Component, Input, OnChanges, OnDestroy, OnInit, SimpleChanges, ViewChild} from "@angular/core"; -import {Indicator, IndicatorPath, Stakeholder} from "../utils/entities/stakeholder"; +import {Indicator, IndicatorPath, IndicatorType, Section, Stakeholder} from "../utils/entities/stakeholder"; import {IndicatorUtils} from "../utils/indicator-utils"; import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms"; import {AlertModal} from "../openaireLibrary/utils/modal/alert"; @@ -35,13 +35,14 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV /** * Editable indicator */ + public section: Section; public indicator: Indicator; public index: number = -1; /** * Displayed chart and numbers base on Top filters */ - public displayCharts: Indicator[] = []; - public displayNumbers: Indicator[] = []; + public displayCharts: Section[] = []; + public displayNumbers: Section[] = []; /** * Top filters */ @@ -82,7 +83,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV ngAfterViewInit(): void { if (document !== undefined) { - let callback = (list): void => { + let callback = (list, type: IndicatorType): void => { let items: HTMLCollection = list.current.children; let reordered = []; for (let i = 0; i < items.length; i++) { @@ -90,10 +91,30 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV reordered.push(items.item(i).id); } } - this.reorderIndicators(list.current.id, reordered); + this.reorderIndicators(list.current.id.toString().split('-')[1], type, reordered); }; - this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart', callback)); - this.subscriptions.push(UIkit.util.on(document, 'moved', '#number', callback)); + this.numbers.forEach((section) => { + this.subscriptions.push(UIkit.util.on(document, 'moved', '#chart' + section._id, (list): void => { + callback(list, "number"); + })); + this.subscriptions.push(UIkit.util.on(document, 'added', '#chart' + section._id, (list): void => { + callback(list, "number"); + })); + this.subscriptions.push(UIkit.util.on(document, 'removed', '#chart' + 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"); + })); + }); } } @@ -175,66 +196,67 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV this.displayNumbers = this.filterByKeyword(this.numbers, value); } - private filterChartType(indicators: Indicator[], value): Indicator[] { + private filterChartType(sections: Section[], value): Section[] { if (value === 'all') { - return indicators; + return sections; } else { - return indicators.filter(indicator => - indicator.indicatorPaths.filter(indicatorPath => indicatorPath.type === value).length > 0); + return sections.filter(section => + section.indicators = section.indicators.filter(indicator => + indicator.indicatorPaths.filter(indicatorPath => indicatorPath.type === value).length > 0)); } } - private filterPrivacy(indicators: Indicator[], value): Indicator[] { + private filterPrivacy(sections: Section[], value): Section[] { if (value === 'all') { - return indicators; + return sections; } else { - return indicators.filter(indicator => indicator.isPublic === value); + return sections.filter(section => + section.indicators = section.indicators.filter(indicator => indicator.isPublic === value)); } } - private filterStatus(indicators: Indicator[], value): Indicator[] { + private filterStatus(sections: Section[], value): Section[] { if (value === 'all') { - return indicators; + return sections; } else { - return indicators.filter(indicator => indicator.isActive === value); + return sections.filter(section => + section.indicators = section.indicators.filter(indicator => indicator.isActive === value)); } } - private filterByKeyword(indicators: Indicator[], value): Indicator[] { + private filterByKeyword(sections: Section[], value): Section[] { if (value === null || value === '') { - return indicators; + return sections; } else { - return indicators.filter(indicator => (indicator.name && indicator.name.toLowerCase().includes(value.toLowerCase())) - || (indicator.description && indicator.description.toLowerCase().includes(value.toLowerCase()))); + return sections.filter(section => + section.indicators = section.indicators.filter(indicator => (indicator.name && indicator.name.toLowerCase().includes(value.toLowerCase())) + || (indicator.description && indicator.description.toLowerCase().includes(value.toLowerCase())))); } } - get charts(): Indicator[] { + get charts(): Section[] { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts; } - set charts(indicators: Indicator[]) { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts = indicators; + set charts(sections: Section[]) { + this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].charts = sections; } - get numbers(): Indicator[] { + get numbers(): Section[] { return this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers; } - set numbers(indicators: Indicator[]) { - this.stakeholder.topics[this.topicIndex].categories[this.categoryIndex].subCategories[this.subcategoryIndex].numbers = indicators; + 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 canNumbersReorder(): boolean { - return this.displayNumbers.length === this.numbers.length && this.grid; - } - - get canChartsReorder(): boolean { - return this.displayCharts.length === this.charts.length && this.grid; + get canReorder(): boolean { + return this.filters.value.chartType === 'all' && this.filters.value.privacy === 'all' && + this.filters.value.status === 'all' && this.filters.value.keyword === '' && this.grid; } get canEdit() { @@ -277,7 +299,7 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV let index = this.indicatorPaths.length - 1; this.urlSubscriptions.push(this.indicatorPaths.at(index).get('url').valueChanges.subscribe(value => { if (this.indicatorPaths.at(index).get('url').valid) { - let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(value), value, 'bar',this.stakeholder); + let indicatorPath: IndicatorPath = this.indicatorUtils.generateIndicatorByChartUrl(this.statisticsService.getChartSource(value), value, 'bar', this.stakeholder); let parameters = this.getParametersAsFormArray(indicatorPath); (this.indicatorPaths.at(index) as FormGroup).setControl('parameters', parameters); if (!this.indicator.indicatorPaths[index]) { @@ -314,16 +336,16 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV return parameters; } - public editChartIndicatorOpen(id = null) { + public editChartIndicatorOpen(section: Section, id = null) { this.urlSubscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } }); - this.index = (id) ? this.charts.findIndex(value => value._id === id) : -1; - console.log(this.index); + this.section = section; + this.index = (id) ? section.indicators.findIndex(value => value._id === id) : -1; if (this.index !== -1) { - this.indicator = HelperFunctions.copy(this.charts[this.index]); + this.indicator = HelperFunctions.copy(this.section.indicators[this.index]); this.indicatorFb = this.fb.group({ id: this.fb.control(this.indicator._id), name: this.fb.control(this.indicator.name/*, Validators.required*/), @@ -371,45 +393,45 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV 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.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.charts[this.index] = indicator; + this.section.indicators[this.index] = indicator; } else { - this.charts.push(indicator); + this.section.indicators.push(indicator); } this.filterCharts(); - this.stakeholderService.setStakeholder(this.stakeholder); this.indicatorFb = null; }, error => { this.indicatorFb = null; }); } - reorderIndicators(type: string, indicatorIds: string[]) { + reorderIndicators(sectionId: string, type: IndicatorType, indicatorIds: string[]) { 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.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 = indicators; + this.charts.find(section => section._id === sectionId).indicators = indicators; this.filterCharts(); } else { - this.numbers = indicators; + this.numbers.find(section => section._id === sectionId).indicators = indicators; this.filterNumbers(); } - this.stakeholderService.setStakeholder(this.stakeholder); }); } hasDifference(index: number): boolean { let hasDifference = false; this.indicatorPaths.at(index).value.parameters.forEach((parameter) => { - if(parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { + if (parameter.value !== this.indicator.indicatorPaths[index].parameters[parameter.key]) { hasDifference = true; return; } @@ -425,12 +447,9 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV }); } - deleteIndicatorOpen(id: string, type: string = 'chart') { - if (type === 'chart') { - this.indicator = this.charts.find(value => value._id == id); - } else { - this.indicator = this.numbers.find(value => value._id == id); - } + deleteIndicatorOpen(section: Section, indicatorId: string, type: string = 'chart') { + this.section = section; + this.indicator = section.indicators.find(value => value._id == indicatorId); this.deleteModal.alertTitle = 'Delete indicator'; this.deleteModal.cancelButtonText = 'No'; this.deleteModal.okButtonText = 'Yes'; @@ -443,43 +462,43 @@ export class IndicatorsComponent implements OnInit, OnDestroy, OnChanges, AfterV 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).subscribe(() => { if (this.indicator.type === 'chart') { - this.charts.splice(this.index, 1); + this.charts.find(section => section._id === this.section._id).indicators.splice(this.index, 1); } else { - this.numbers.splice(this.index, 1); + this.numbers.find(section => section._id === this.section._id).indicators.splice(this.index, 1); } - this.stakeholderService.setStakeholder(this.stakeholder); }); } - toggleIndicatorStatus(indicator: Indicator) { + toggleIndicatorStatus(sectionId: string, indicator: 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, + sectionId, indicator._id ]; this.stakeholderService.toggleStatus(this.properties.monitorServiceAPIURL, path).subscribe(isActive => { indicator.isActive = isActive; - this.stakeholderService.setStakeholder(this.stakeholder); }); } - toggleIndicatorAccess(indicator: Indicator) { + toggleIndicatorAccess(sectionId: string, indicator: 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, + sectionId, indicator._id ]; this.stakeholderService.toggleAccess(this.properties.monitorServiceAPIURL, path).subscribe(isPublic => { indicator.isPublic = isPublic; - this.stakeholderService.setStakeholder(this.stakeholder); }); } } diff --git a/src/app/topic/topic-routing.module.ts b/src/app/topic/topic-routing.module.ts index d4c5595..3a740d1 100644 --- a/src/app/topic/topic-routing.module.ts +++ b/src/app/topic/topic-routing.module.ts @@ -3,6 +3,7 @@ import {RouterModule} from '@angular/router'; import {FreeGuard} from '../openaireLibrary/login/freeGuard.guard'; import {PreviousRouteRecorder} from '../openaireLibrary/utils/piwik/previousRouteRecorder.guard'; import {TopicComponent} from "./topic.component"; +import {CanExitGuard} from "../openaireLibrary/utils/can-exit.guard"; @NgModule({ imports: [ @@ -11,7 +12,7 @@ import {TopicComponent} from "./topic.component"; path: '', component: TopicComponent, canActivate: [FreeGuard], - canDeactivate: [PreviousRouteRecorder] + canDeactivate: [PreviousRouteRecorder, CanExitGuard] } ]) ] diff --git a/src/app/topic/topic.component.html b/src/app/topic/topic.component.html index 3f3599f..39294e0 100644 --- a/src/app/topic/topic.component.html +++ b/src/app/topic/topic.component.html @@ -113,7 +113,7 @@
- { if (stakeholder) { - this.stakeholder = HelperFunctions.copy(stakeholder); + this.stakeholder = stakeholder; this.topicIndex = this.stakeholder.topics.findIndex(topic => topic.alias === params['topic']); if (this.topicIndex === -1) { this.navigateToError(); @@ -86,11 +87,16 @@ export class TopicComponent implements OnInit, OnDestroy { } public ngOnDestroy() { + } + + canExit():boolean { this.subscriptions.forEach(value => { if (value instanceof Subscriber) { value.unsubscribe(); } }); + this.stakeholderService.setStakeholder(this.stakeholder); + return true; } public saveElement() { @@ -126,7 +132,7 @@ export class TopicComponent implements OnInit, OnDestroy { ), isActive: this.fb.control(topic.isActive), isPublic: this.fb.control(topic.isPublic), - isDefault: this.fb.control(topic.isDefault), + defaultId: this.fb.control(topic.defaultId), categories: this.fb.control(topic.categories) }); this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { @@ -152,7 +158,6 @@ export class TopicComponent implements OnInit, OnDestroy { let path = [this.stakeholder._id]; let callback = (topic: Topic): void => { this.stakeholder.topics[this.index] = topic; - this.stakeholderService.setStakeholder(this.stakeholder); }; this.save('Topic has been successfully saved', path, this.form.value, callback, true); } @@ -192,7 +197,6 @@ export class TopicComponent implements OnInit, OnDestroy { ]; let callback = (): void => { this.stakeholder.topics.splice(this.index, 1); - this.stakeholderService.setStakeholder(this.stakeholder); }; this.delete('Topic has been successfully be deleted', path, callback, true); } @@ -219,7 +223,7 @@ export class TopicComponent implements OnInit, OnDestroy { ), isActive: this.fb.control(category.isActive), isPublic: this.fb.control(category.isPublic), - isDefault: this.fb.control(category.isDefault), + defaultId: this.fb.control(category.defaultId), subCategories: this.fb.control(category.subCategories) }); this.subscriptions.push(this.form.get('name').valueChanges.subscribe(value => { @@ -253,7 +257,6 @@ export class TopicComponent implements OnInit, OnDestroy { } else { this.stakeholder.topics[this.topicIndex].categories[this.index] = HelperFunctions.copy(category); } - this.stakeholderService.setStakeholder(this.stakeholder); }; if (this.index === -1) { this.save('Category has been successfully created', path, this.form.value, callback); @@ -300,7 +303,6 @@ export class TopicComponent implements OnInit, OnDestroy { ]; let callback = (): void => { this.stakeholder.topics[this.topicIndex].categories.splice(this.index, 1); - this.stakeholderService.setStakeholder(this.stakeholder); }; this.delete('Category has been successfully be deleted', path, callback); } @@ -318,7 +320,7 @@ export class TopicComponent implements OnInit, OnDestroy { ), isActive: this.fb.control(subCategory.isActive), isPublic: this.fb.control(subCategory.isPublic), - isDefault: this.fb.control(subCategory.isDefault), + defaultId: this.fb.control(subCategory.defaultId), charts: this.fb.control(subCategory.charts), numbers: this.fb.control(subCategory.numbers) }); @@ -357,7 +359,6 @@ export class TopicComponent implements OnInit, OnDestroy { } else { this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories[this.index] = subCategory; } - this.stakeholderService.setStakeholder(this.stakeholder); }; if (this.index === -1) { this.save('Subcategory has been successfully created', path, this.form.value, callback); @@ -407,7 +408,6 @@ export class TopicComponent implements OnInit, OnDestroy { ]; let callback = (): void => { this.stakeholder.topics[this.topicIndex].categories[this.selectedCategoryIndex].subCategories.splice(this.index, 1); - this.stakeholderService.setStakeholder(this.stakeholder); }; this.delete('Subcategory has been successfully be deleted', path, callback); } @@ -482,7 +482,6 @@ export class TopicComponent implements OnInit, OnDestroy { private toggleStatus(element: Topic | Category | SubCategory, path: string[]) { this.stakeholderService.toggleStatus(this.properties.monitorServiceAPIURL, path).subscribe(isActive => { element.isActive = isActive; - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification(StringUtils.capitalize(this.type) + ' has been successfully ' + (isActive ? 'activated' : 'deactivated'), { status: 'success', timeout: 3000, @@ -500,7 +499,6 @@ export class TopicComponent implements OnInit, OnDestroy { private toggleAccess(element: Topic | Category | SubCategory, path: string[]) { this.stakeholderService.toggleAccess(this.properties.monitorServiceAPIURL, path).subscribe(isPublic => { element.isPublic = isPublic; - this.stakeholderService.setStakeholder(this.stakeholder); UIkit.notification(StringUtils.capitalize(this.type) + ' has been successfully changed to ' + (isPublic ? 'public' : 'private'), { status: 'success', timeout: 3000, diff --git a/src/app/utils/entities/stakeholder.ts b/src/app/utils/entities/stakeholder.ts index 322c1a5..9d26747 100644 --- a/src/app/utils/entities/stakeholder.ts +++ b/src/app/utils/entities/stakeholder.ts @@ -1,40 +1,47 @@ import {SafeResourceUrl} from "@angular/platform-browser"; import {IndicatorUtils} from "../indicator-utils"; +import {stat} from "fs"; export const ChartHelper = { prefix: "((__", suffix: "__))" }; +export type StakeholderType = 'funder' | 'ri' | 'project' | 'organization'; +export type IndicatorType = 'number' | 'chart'; +export type IndicatorWidth = 'small' | 'medium' | 'large'; +export type IndicatorPathType = 'table' | 'bar' | 'column' | 'pie' | 'line' | 'other'; +export type SourceType = 'statistics' | 'search' | 'metrics' | 'stats-tool' | 'old' | 'image'; + export class Stakeholder { _id: string; - type: string; + type: StakeholderType; index_id; index_name: string; index_shortName: string; alias: string; - isDefaultProfile: boolean; + defaultId: string; isActive: boolean; isPublic: boolean; - creationDate: string; - updateDate: string; + creationDate: Date; + updateDate: Date; managers: string[]; logoUrl:string; topics: Topic[]; - constructor(id: string, type: string, index_id, index_name: string, index_shortName: string, isDefaultProfile: boolean, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string) { - this.initializeFunder(id, type, index_id, index_name, index_shortName, isDefaultProfile, alias, isActive, isPublic, logoUrl); + constructor(id: string, type: StakeholderType, index_id, index_name: string, index_shortName: string, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string, defaultId: string = null) { + this.initializeFunder(id, type, index_id, index_name, index_shortName, defaultId, alias, isActive, isPublic, logoUrl); this.topics = []; this.managers = []; } - initializeFunder(id: string, type: string, index_id, index_name: string, index_shortName: string, isDefaultProfile: boolean, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string) { + initializeFunder(id: string, type: StakeholderType, index_id, index_name: string, index_shortName: string, defaultId: string, alias: string, isActive: boolean, isPublic: boolean, logoUrl:string) { this._id = id; this.type = type; this.index_id = index_id; this.index_name = index_name; this.index_shortName = index_shortName; - this.isDefaultProfile = isDefaultProfile; + this.defaultId = defaultId; this.alias = alias; this.isActive = isActive; this.isPublic = isPublic; @@ -289,17 +296,17 @@ export class Topic { description: string; isActive: boolean; isPublic: boolean; - isDefault: boolean; + defaultId: string; categories: Category[]; - constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, isDefault: boolean = true) { + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { this._id = null; this.name = name; this.description = description; this.alias = alias; this.isActive = isActive; this.isPublic = isPublic; - this.isDefault = isDefault; + this.defaultId = defaultId; this.categories = []; } } @@ -311,18 +318,17 @@ export class Category { description: string; isActive: boolean; isPublic: boolean; - isOverview: boolean; - isDefault: boolean; + defaultId: string; subCategories: SubCategory[]; - constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, isDefault: boolean = true) { + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { this._id = null; this.name = name; this.description = description; this.alias = alias; this.isActive = isActive; this.isPublic = isPublic; - this.isDefault = isDefault; + this.defaultId = defaultId; this.subCategories = []; } } @@ -334,40 +340,58 @@ export class SubCategory { description: string; isActive: boolean; isPublic: boolean; - isDefault: boolean; - charts: Indicator[]; - numbers: Indicator[]; + defaultId: string; + charts: Section[]; + numbers: Section[]; recommendedFor:string[]; - constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, isDefault: boolean = true) { + constructor(name: string, description: string, alias: string, isActive: boolean, isPublic: boolean, defaultId: string = null) { this._id = null; this.name = name; this.description = description; this.alias = alias; this.isActive = isActive; this.isPublic = isPublic; - this.isDefault = isDefault; - this.charts = []; - this.numbers = []; + this.defaultId = defaultId; + this.charts = [new Section("chart")]; + this.numbers = [new Section("number")]; this.recommendedFor= []; } } +export class Section { + _id: string; + title: string; + defaultId: string; + stakeholderId: string; + type: IndicatorType; + indicators: Indicator[]; + + constructor(type: IndicatorType, title: string = null, defaultId: string = null, stakeholderId: string = null) { + this._id = null; + this.title = title; + this.type = type; + this.defaultId = defaultId; + this.stakeholderId = stakeholderId; + this.indicators = []; + } +} + export class Indicator { _id: string; name: string; description: string; - type: string; //number,chart - width: string; //small,medium,large + type: IndicatorType; + width: IndicatorWidth; tags: string[]; isActive: boolean; isPublic: boolean; - isDefault: boolean; + defaultId: string; indicatorPaths: IndicatorPath[]; recommendedFor:string[]; - constructor(name: string, description: string, type: string, width: string, isActive: boolean, isPublic: boolean, indicatorPaths: IndicatorPath[]) { + constructor(name: string, description: string, type: IndicatorType, width: IndicatorWidth, isActive: boolean, isPublic: boolean, indicatorPaths: IndicatorPath[], defaultId: string = null) { this._id = null; this.name = name; this.description = description; @@ -375,6 +399,7 @@ export class Indicator { this.width = width; this.isActive = isActive; this.isPublic = isPublic; + this.defaultId = defaultId; this.indicatorPaths = indicatorPaths; this.recommendedFor = []; } @@ -382,8 +407,8 @@ export class Indicator { } export class IndicatorPath { - type: string; // for charts is type of chart {table, bar, column, etc} - source: string;// for numbers is the service {statistics, search, metrics} for charts is the tool {stats-tool,old,metrics, image} + type: IndicatorPathType; + source: SourceType; url: string; safeResourceUrl: SafeResourceUrl; // initialize on front end jsonPath: string[]; @@ -391,7 +416,7 @@ export class IndicatorPath { parameters: any; filters: any; - constructor(type: string, source: string, url: string, chartObject: string, jsonPath: string[]) { + constructor(type: IndicatorPathType, source: SourceType, url: string, chartObject: string, jsonPath: string[]) { this.type = type; this.url = url; this.source = source; diff --git a/src/app/utils/entities/stakeholderCreator.ts b/src/app/utils/entities/stakeholderCreator.ts index 9482e32..73c9959 100644 --- a/src/app/utils/entities/stakeholderCreator.ts +++ b/src/app/utils/entities/stakeholderCreator.ts @@ -4,7 +4,7 @@ import {IndicatorUtils} from "../indicator-utils"; export class StakeholderCreator { static createFunderDefaultProfile():Stakeholder{ - let funder:Stakeholder = new Stakeholder(null,"funder","_funder_id_","_funder_name_","_FSN_",true,"deafult_funder",true,true, null); + let funder:Stakeholder = new Stakeholder(null,"funder","_funder_id_","_funder_name_","_FSN_","deafault_funder",true,true, null); funder.topics.push(StakeholderCreator.createResearchProductionTopic(funder)); funder.topics.push(StakeholderCreator.createOSTopic(funder)); let collaboration = new Topic("Collaboration","Indexes for collaboration","collaboration", true, true); @@ -32,7 +32,7 @@ export class StakeholderCreator { } static createEmptyCategory(name: string, description: string, alias: string):Category{ let cat:Category = new Category(name, description, alias,true,true); - cat.subCategories.push(new SubCategory("Overview","","overview",true,true,true)); + cat.subCategories.push(new SubCategory("Overview","","overview",true,true)); return cat; } @@ -81,14 +81,14 @@ export class StakeholderCreator { let n_total = new Indicator("Total " + typePlural, null, "number", "small", true, true, [new IndicatorPath(null, "search", "/" + dbTypePlural + "/count?fq=" + (encodeURIComponent("relfunderid exact " + stakeholder.index_id)) + "&format=json", null, ["total"])]); n_total.indicatorPaths[0].filters["fundingL0"] = "&fq=relfundinglevel0_name exact " + ChartHelper.prefix + 'fundingL0' + ChartHelper.suffix; - pubDefSub.numbers.push(n_total); + pubDefSub.numbers[0].indicators.push(n_total); } if( dbType != "publication" && index == 0) { let n_linkedPubs = this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Publications","publication"); // new Indicator("Linked with Publications", null, "number", "small", true, true, [new IndicatorPath(null, "search", // "/resources?query="+encodeURIComponent(" ( (oaftype exact result) and (resulttypeid exact " + dbTypePlural + ") and (relresulttype=publication) )")+"&fq=" + (encodeURIComponent("relfunderid exact " + stakeholder.index_id)) + "&page=0&size=0&format=json", null, ["meta","total"])]); - pubDefSub.numbers.push(n_linkedPubs); + pubDefSub.numbers[0].indicators.push(n_linkedPubs); } let res_timeline = new Indicator("",null, "chart","small",true, true,[new IndicatorPath("column", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"'+typePlural+'","type":"'+ChartHelper.prefix+'type'+ChartHelper.suffix+'","query":{"select":[{"field":"'+dbType+'","aggregate":"count"},{"field":"'+dbType+'.year","aggregate":null}],"filters":[{"groupFilters":[{"field":"'+dbType+'.project.funder","type":"=","values":["'+ChartHelper.prefix+'funder_name'+ChartHelper.suffix+'"]}],"op":"AND"},{"groupFilters":[{"field":"'+dbType+'.year","type":">=","values":["'+ChartHelper.prefix+'start_year'+ChartHelper.suffix+'"]},{"field":"'+dbType+'.year","type":"<=","values":["'+ChartHelper.prefix+'end_year'+ChartHelper.suffix+'"]}],"op":"AND"}'+fundingFilter[index]+'],"entity":"'+dbType+'","profile":"OpenAIRE All-inclusive","limit":"0"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"'+ChartHelper.prefix+'title'+ChartHelper.suffix+'"},"subtitle":{},"yAxis":{"title":{"text":"'+typePlural+'"}},"xAxis":{"title":{"text":"Year"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); @@ -96,7 +96,7 @@ export class StakeholderCreator { res_timeline.indicatorPaths[0].parameters["start_year"] = (index == 1?"2014":"2008"); res_timeline.indicatorPaths[0].parameters["end_year"] = "2020"; res_timeline.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); - pubDefSub.charts.push(res_timeline); + pubDefSub.charts[0].indicators.push(res_timeline); if(dbType == "publication" || dbType == "dataset") { @@ -106,13 +106,13 @@ export class StakeholderCreator { '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"select":[{"field":"' + dbType + '","aggregate":"count"},{"field":"' + dbType + '.classification","aggregate":null}],"filters":[{"groupFilters":[{"field":"' + dbType + '.project.funder","type":"=","values":["' + ChartHelper.prefix + 'funder_name' + ChartHelper.suffix + '"]}],"op":"AND"}'+fundingFilter[index]+'],"entity":"' + dbType + '","profile":"OpenAIRE All-inclusive","limit":"0"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Type"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); res_types.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " types", "bar"); res_types.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); - pubDefSub.charts.push(res_types); + pubDefSub.charts[0].indicators.push(res_types); } let res_access_mode = new Indicator("",null, "chart","small",true, true,[new IndicatorPath("pie", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"'+typePlural+'","type":"'+ChartHelper.prefix+'type'+ChartHelper.suffix+'","query":{"select":[{"field":"'+dbType+'","aggregate":"count"},{"field":"'+dbType+'.access mode","aggregate":null}],"filters":[{"groupFilters":[{"field":"'+dbType+'.project.funder","type":"=","values":["'+ChartHelper.prefix+'funder_name'+ChartHelper.suffix+'"]}],"op":"AND"}'+fundingFilter[index]+'],"entity":"' + dbType + '","profile":"OpenAIRE All-inclusive","limit":"0"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"'+ChartHelper.prefix+'title'+ChartHelper.suffix+'"},"subtitle":{},"yAxis":{"title":{"text":"'+typePlural+'"}},"xAxis":{"title":{"text":"Year"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); res_access_mode.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name,chartTitle[index] + typeSingl+" access mode","pie"); res_access_mode.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); - pubDefSub.charts.push(res_access_mode); + pubDefSub.charts[0].indicators.push(res_access_mode); let res_sci_area = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", @@ -120,46 +120,46 @@ export class StakeholderCreator { res_sci_area.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " scientific area", "bar"); res_sci_area.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); res_sci_area.recommendedFor = ["ec__________::EC"]; - pubDefSub.charts.push(res_sci_area); + pubDefSub.charts[0].indicators.push(res_sci_area); let res_programmes = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"select":[{"field":"' + dbType + '","aggregate":"count"},{"field":"' + dbType + '.project.funding level 2","aggregate":null}],"filters":[{"groupFilters":[{"field":"' + dbType + '.project.funder","type":"=","values":["' + ChartHelper.prefix + 'funder_name' + ChartHelper.suffix + '"]}],"op":"AND"},{"groupFilters":[{"field":"' + dbType + '.project.funding level 2","type":"!=","values":[" "]}],"op":"AND"}'+fundingFilter[index]+'],"entity":"' + dbType + '","profile":"OpenAIRE All-inclusive","limit":"30"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Programmes"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); res_programmes.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " programmes", "bar"); res_programmes.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); res_programmes.recommendedFor = ["ec__________::EC"]; - pubDefSub.charts.push(res_programmes); + pubDefSub.charts[0].indicators.push(res_programmes); //{"library":"HighCharts","chartDescription":{"queries":[{"name":"Research Data","type":"bar","query":{"select":[{"field":"dataset","aggregate":"count"},{"field":"dataset.project.funding level 1","aggregate":null}],"filters":[{"groupFilters":[{"field":"dataset.project.funder","type":"=","values":["European Commission"]}],"op":"AND"}],"entity":"dataset","profile":"OpenAIRE All-inclusive","limit":"30"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"Scientific Area"},"subtitle":{},"yAxis":{"title":{}},"xAxis":{"title":{}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":false},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}} let datasource = new Indicator("",null, "chart","small",true, true,[new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"'+typePlural+'","type":"'+ChartHelper.prefix+'type'+ChartHelper.suffix+'","query":{"name":"monitor.'+ChartHelper.prefix+'id'+ChartHelper.suffix+(index==2?".h2020":(index==1?".fp7":""))+'.'+dbTypePlural+'.datasources"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"'+ChartHelper.prefix+'title'+ChartHelper.suffix+'"},"subtitle":{},"yAxis":{"title":{"text":"'+typePlural+'"}},"xAxis":{"title":{"text":"Content provider"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); datasource.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name,chartTitle[index] + typeSingl+" content provider","bar"); datasource.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); - pubDefSub.charts.push(datasource); + pubDefSub.charts[0].indicators.push(datasource); if(dbType == "publication") { let journal = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"name":"monitor.' + ChartHelper.prefix + 'id' + ChartHelper.suffix +(index==2?".h2020":(index==1?".fp7":""))+ '.' + dbTypePlural + '.journals"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Journal"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); journal.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " journal", "bar"); journal.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); - pubDefSub.charts.push(journal); + pubDefSub.charts[0].indicators.push(journal); let repo = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"name":"monitor.' + ChartHelper.prefix + 'id' + ChartHelper.suffix +(index==2?".h2020":(index==1?".fp7":""))+ '.' + dbTypePlural + '.repositories"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Repositories"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); repo.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " repositories", "bar"); repo.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); - pubDefSub.charts.push(repo); + pubDefSub.charts[0].indicators.push(repo); } if(dbType == "dataset") { let repo = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"name":"monitor.' + ChartHelper.prefix + 'id' + ChartHelper.suffix + (index==2?".h2020":(index==1?".fp7":""))+'.' + dbTypePlural + '.drepositories"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Data Repositories"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); repo.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " repositories", "bar"); repo.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); - pubDefSub.charts.push(repo); + pubDefSub.charts[0].indicators.push(repo); let irepo = new Indicator("", null, "chart", "small", true, true, [new IndicatorPath("bar", "stats-tool", "chart?json=", '{"library":"HighCharts","chartDescription":{"queries":[{"name":"' + typePlural + '","type":"' + ChartHelper.prefix + 'type' + ChartHelper.suffix + '","query":{"name":"monitor.' + ChartHelper.prefix + 'id' + ChartHelper.suffix +(index==2?".h2020":(index==1?".fp7":""))+ '.' + dbTypePlural + '.irepositories"}}],"chart":{"backgroundColor":"#FFFFFFFF","borderColor":"#335cadff","borderRadius":0,"borderWidth":0,"plotBorderColor":"#ccccccff","plotBorderWidth":0},"title":{"text":"' + ChartHelper.prefix + 'title' + ChartHelper.suffix + '"},"subtitle":{},"yAxis":{"title":{"text":"' + typePlural + '"}},"xAxis":{"title":{"text":"Institutional repositories"}},"lang":{"noData":"No Data available for the Query"},"exporting":{"enabled":true},"plotOptions":{"series":{"dataLabels":{"enabled":false}}},"legend":{"enabled":true,"align":"center","verticalAlign":"bottom","layout":"horizontal"},"credits":{"href":null,"enabled":true,"text":"Created by OpenAIRE via HighCharts"}}}', null)]); irepo.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, chartTitle[index] + typeSingl + " institutional repositories", "bar"); irepo.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); - pubDefSub.charts.push(irepo); + pubDefSub.charts[0].indicators.push(irepo); } if(index ==0) { @@ -168,7 +168,7 @@ export class StakeholderCreator { pid.indicatorPaths[0].parameters = IndicatorPath.createParameters(stakeholder.index_name, typeSingl + " PIDs", "pie"); pid.indicatorPaths[0].parameters["id"] = stakeholder.index_shortName.toLowerCase(); pid.indicatorPaths[0].filters = IndicatorPath.createResultFilters(dbType); - pubDefSub.charts.push(pid); + pubDefSub.charts[0].indicators.push(pid); } return pubDefSub; } @@ -192,9 +192,9 @@ export class StakeholderCreator { } static createOASub(stakeholder:Stakeholder,typePlural, typeSingl, dbType, dbTypePlural ):SubCategory { let sub:SubCategory = new SubCategory(typePlural, null, dbTypePlural, true, true); - sub.charts = sub.charts.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 0 )); - sub.charts = sub.charts.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 1 )); - sub.charts = sub.charts.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 2 )); + sub.charts[0].indicators = sub.charts[0].indicators.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 0 )); + sub.charts[0].indicators = sub.charts[0].indicators.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 1 )); + sub.charts[0].indicators = sub.charts[0].indicators.concat( this.createOAPerType(stakeholder,typePlural, typeSingl, dbType, dbTypePlural, 2 )); return sub; } static createOAPerType(stakeholder:Stakeholder,typePlural, typeSingl, dbType, dbTypePlural, index:number):Indicator[] { @@ -299,7 +299,7 @@ export class StakeholderCreator { linked.subCategories.push(this.createOSOverviewPerType(stakeholder,"Other research products","Other research product","other","other")); let openInfra:Category = new Category("Open Infrastructures","Indicators based on the use of services for generating, producing and publishing research","open-infrastructures",true,true); - openInfra.subCategories.push(new SubCategory("Overview","","overview",true,true,true)); + openInfra.subCategories.push(new SubCategory("Overview","","overview",true,true)); topic.categories.push(openInfra); return topic; @@ -309,16 +309,16 @@ export class StakeholderCreator { let pubDefSub = new SubCategory(typePlural, null, dbTypePlural, true, true); if( dbType != "publication") { - pubDefSub.numbers.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Publications","publication")); + pubDefSub.numbers[0].indicators.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Publications","publication")); } if( dbType != "dataset") { - pubDefSub.numbers.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Research data","dataset")); + pubDefSub.numbers[0].indicators.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Research data","dataset")); } if( dbType != "software") { - pubDefSub.numbers.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Software","software")); + pubDefSub.numbers[0].indicators.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Software","software")); } if( dbType != "other") { - pubDefSub.numbers.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Other Research products","other")); + pubDefSub.numbers[0].indicators.push(this.createLinkToIndicator(stakeholder,typePlural,typeSingl, dbType,"Other Research products","other")); } return pubDefSub; } @@ -382,13 +382,13 @@ export class StakeholderCreator { let chart1 = new Indicator( "Chart title goes here","Chart description goes here", "chart","medium",true, true, - [new IndicatorPath("?", "fake","https://visme.co/blog/wp-content/uploads/2017/03/Dogs-vs-Cats-How-much-they-miss-you-relative-to-the-time-you-are-gone.png", null, null)]); - let chart2 = new Indicator("Chart title goes here","Chart description goes here", "chart","medium",true, true, [new IndicatorPath("?", "fake","https://static.boredpanda.com/blog/wp-content/uuuploads/funny-graphs-2/funny-graphs-legs.jpg", null, null)]); - subCat1.charts.push(chart1); - subCat2.charts.push(chart2); + [new IndicatorPath("other", "image","https://visme.co/blog/wp-content/uploads/2017/03/Dogs-vs-Cats-How-much-they-miss-you-relative-to-the-time-you-are-gone.png", null, null)]); + let chart2 = new Indicator("Chart title goes here","Chart description goes here", "chart","medium",true, true, [new IndicatorPath("other", "image","https://static.boredpanda.com/blog/wp-content/uuuploads/funny-graphs-2/funny-graphs-legs.jpg", null, null)]); + subCat1.charts[0].indicators.push(chart1); + subCat2.charts[0].indicators.push(chart2); - defSub.charts.push(chart1); - defSub.charts.push(chart2); + defSub.charts[0].indicators.push(chart1); + defSub.charts[0].indicators.push(chart2); return topic; } } diff --git a/src/app/utils/indicator-utils.ts b/src/app/utils/indicator-utils.ts index ead5500..8f9a66f 100644 --- a/src/app/utils/indicator-utils.ts +++ b/src/app/utils/indicator-utils.ts @@ -1,4 +1,12 @@ -import {ChartHelper, Indicator, IndicatorPath, Stakeholder, SubCategory, Topic} from "./entities/stakeholder"; +import { + ChartHelper, + Indicator, + IndicatorPath, IndicatorPathType, + SourceType, + Stakeholder, + SubCategory, + Topic +} from "./entities/stakeholder"; import {AbstractControl, ValidatorFn, Validators} from "@angular/forms"; import {Option} from "../openaireLibrary/dashboard/sharedComponents/input/input.component"; @@ -33,44 +41,49 @@ export class StakeholderUtils { let subTokeep: SubCategory[] = []; for (let subCategory of category.subCategories) { subCategory._id = null; - let chartsTokeep: Indicator[] = []; if (subCategory.recommendedFor.length == 0 || subCategory.recommendedFor.indexOf(funder.index_id) != -1) { subTokeep.push(subCategory); } - for (let indicator of subCategory.charts) { - indicator._id = null; - if (indicator.recommendedFor.length == 0 || indicator.recommendedFor.indexOf(funder.index_id) != -1) { - chartsTokeep.push(indicator); - } - for (let indicatorPath of indicator.indicatorPaths) { - if (indicatorPath.parameters) { - Object.keys(indicatorPath.parameters).forEach(key => { - if (indicatorPath.parameters[key].indexOf("_funder_name_") != -1) { - indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_name_", funder.index_name); - } else if (indicatorPath.parameters[key].indexOf("_funder_id_") != -1) { - indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_id_", funder.index_id); - } else if (indicatorPath.parameters[key].indexOf("_fsn_") != -1) { - indicatorPath.parameters[key] = indicatorPath.parameters[key].toString().replace("_fsn_", funder.index_shortName.toLowerCase()); - } - }); + for (let section of subCategory.charts) { + let chartsTokeep: Indicator[] = []; + section._id = null; + for (let indicator of section.indicators) { + indicator._id = null; + if (indicator.recommendedFor.length == 0 || indicator.recommendedFor.indexOf(funder.index_id) != -1) { + chartsTokeep.push(indicator); + } + for (let indicatorPath of indicator.indicatorPaths) { + if (indicatorPath.parameters) { + Object.keys(indicatorPath.parameters).forEach(key => { + if (indicatorPath.parameters[key].indexOf("_funder_name_") != -1) { + indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_name_", funder.index_name); + } else if (indicatorPath.parameters[key].indexOf("_funder_id_") != -1) { + indicatorPath.parameters[key] = indicatorPath.parameters[key].replace("_funder_id_", funder.index_id); + } else if (indicatorPath.parameters[key].indexOf("_fsn_") != -1) { + indicatorPath.parameters[key] = indicatorPath.parameters[key].toString().replace("_fsn_", funder.index_shortName.toLowerCase()); + } + }); + } } } - + section.indicators = chartsTokeep; } - subCategory.charts = chartsTokeep; - for (let indicator of subCategory.numbers) { - indicator._id = null; - for (let indicatorPath of indicator.indicatorPaths) { - indicatorPath.url = indicatorPath.url.replace("_funder_id_", funder.index_id); - // if(indicatorPath.parameters) { - // indicatorPath.parameters.forEach((value: string, key: string) => { - // if (value.indexOf("_funder_name_")!=-1) { - // indicatorPath.parameters.set(key,value.toString().replace("_funder_name_", funder.index_name)); - // }else if (value.indexOf("_fsn_")!=-1) { - // indicatorPath.parameters.set(key,value.toString().replace("_fsn_", funder.index_shortName.toLowerCase())); - // } - // }); - // } + for (let section of subCategory.numbers) { + section._id = null; + for(let indicator of section.indicators) { + indicator._id = null; + for (let indicatorPath of indicator.indicatorPaths) { + indicatorPath.url = indicatorPath.url.replace("_funder_id_", funder.index_id); + // if(indicatorPath.parameters) { + // indicatorPath.parameters.forEach((value: string, key: string) => { + // if (value.indexOf("_funder_name_")!=-1) { + // indicatorPath.parameters.set(key,value.toString().replace("_funder_name_", funder.index_name)); + // }else if (value.indexOf("_fsn_")!=-1) { + // indicatorPath.parameters.set(key,value.toString().replace("_fsn_", funder.index_shortName.toLowerCase())); + // } + // }); + // } + } } } @@ -200,8 +213,8 @@ export class IndicatorUtils { return indicator; } - generateIndicatorByChartUrl(source: string, url: string, type: string = null, stakeholder:Stakeholder): IndicatorPath { - let indicatorPath = new IndicatorPath("", source, "", "", []); + generateIndicatorByChartUrl(source: SourceType, url: string, type: IndicatorPathType = null, stakeholder:Stakeholder): IndicatorPath { + let indicatorPath = new IndicatorPath('other', source, "", "", []); if (source === 'stats-tool') { indicatorPath.url = url.split("json=")[0] + "json="; indicatorPath.url = indicatorPath.url.split("/")[indicatorPath.url.split("/").length - 1]; @@ -234,7 +247,7 @@ export class IndicatorUtils { return indicatorPath; } - private extractType(obj, indicatorPath: IndicatorPath): string { + private extractType(obj, indicatorPath: IndicatorPath): IndicatorPathType { let defaultTypes = ["column", "bar", "pie"]; let type = obj["chartDescription"]["queries"][0]["type"]; if (defaultTypes.indexOf(type) == -1) { diff --git a/src/app/utils/services/statistics.service.ts b/src/app/utils/services/statistics.service.ts index 8147d4f..05e970c 100644 --- a/src/app/utils/services/statistics.service.ts +++ b/src/app/utils/services/statistics.service.ts @@ -2,6 +2,7 @@ import {Injectable} from '@angular/core'; import {HttpClient} from "@angular/common/http"; import {EnvironmentSpecificService} from "../../openaireLibrary/utils/properties/environment-specific.service"; import {Observable} from "rxjs"; +import {SourceType} from "../entities/stakeholder"; @Injectable({ @@ -10,7 +11,7 @@ import {Observable} from "rxjs"; export class StatisticsService { numberSources: Map = new Map(); - chartSources: Map = new Map(); + chartSources: Map = new Map(); constructor(private http:HttpClient, private environmentSpecificService: EnvironmentSpecificService) { this.environmentSpecificService.subscribeEnvironment().subscribe(properties => { @@ -28,12 +29,12 @@ export class StatisticsService { return this.http.get(this.numberSources.get(source) + url); } - getChartUrl(source: string, url: string): string { + getChartUrl(source: SourceType, url: string): string { return this.chartSources.get(source) + url; } - getChartSource(url: string): string { - let source = 'image'; + getChartSource(url: string): SourceType { + let source: SourceType = 'image'; this.chartSources.forEach((value, key) => { if(value !== '' && url.indexOf(value) !== -1) { source = key;