Project

General

Profile

1
import {ChangeDetectorRef, Component, OnDestroy, OnInit} from '@angular/core';
2
import {ActivatedRoute, Params, Router} from '@angular/router';
3
import {DomSanitizer, Meta, Title} from '@angular/platform-browser';
4
import {EnvProperties} from '../openaireLibrary/utils/properties/env-properties';
5

    
6
import {PiwikService} from '../openaireLibrary/utils/piwik/piwik.service';
7
import {StringUtils} from '../openaireLibrary/utils/string-utils.class';
8

    
9
import {ErrorCodes} from '../openaireLibrary/utils/properties/errorCodes';
10
import {ErrorMessagesComponent} from '../openaireLibrary/utils/errorMessages.component';
11
import {HelperService} from "../openaireLibrary/utils/helper/helper.service";
12
import {SEOService} from "../openaireLibrary/sharedComponents/SEO/SEO.service";
13
import {StakeholderService} from "../openaireLibrary/monitor/services/stakeholder.service";
14
import {Category, ChartHelper, IndicatorPath, Stakeholder, SubCategory, Topic} from "../openaireLibrary/monitor/entities/stakeholder";
15
import {StatisticsService} from "../utils/services/statistics.service";
16
import {IndicatorUtils, StakeholderUtils} from "../utils/indicator-utils";
17
import {LayoutService} from "../openaireLibrary/dashboard/sharedComponents/sidebar/layout.service";
18
import {FormBuilder, FormControl} from "@angular/forms";
19
import {IDeactivateComponent} from "../openaireLibrary/utils/can-exit.guard";
20
import {Subscription} from "rxjs";
21
import {Session, User} from "../openaireLibrary/login/utils/helper.class";
22
import {MenuItem} from "../openaireLibrary/sharedComponents/menu";
23
import {UserManagementService} from "../openaireLibrary/services/user-management.service";
24
import {StakeholderCreator} from "../utils/entities/stakeholderCreator";
25

    
26
@Component({
27
  selector: 'monitor',
28
  templateUrl: 'monitor.component.html',
29
  styleUrls:['monitor.component.css']
30
})
31
export class MonitorComponent implements OnInit, OnDestroy, IDeactivateComponent {
32
  private static sidebarStatus: {
33
    id;
34
    status;
35
  };
36
  public user: User;
37
  public userMenuItems: MenuItem[] = [new MenuItem("", "My profile", "", "", false, [], [], {})];
38
  public subscriptions: any[] = [];
39
  public piwiksub: any;
40
  public pageContents = null;
41
  public divContents = null;
42
  public status: number;
43
  public loading: boolean = true;
44
  public isViewPublic: boolean = false;
45
  public indicatorUtils: IndicatorUtils = new IndicatorUtils();
46
  public stakeholderUtils: StakeholderUtils = new StakeholderUtils();
47
  public activeTopic: Topic = null;
48
  public activeCategory: Category = null;
49
  public activeSubCategory: SubCategory = null;
50
  public sideBarItems: MenuItem[] = [];
51
  public topBarItems: MenuItem[] = [];
52
  public errorCodes: ErrorCodes;
53
  public stakeholder: Stakeholder;
54
  public numberResults: Map<string, number> = new Map<string, number>();
55
  public chartsActiveType: Map<string, IndicatorPath> = new Map<string, IndicatorPath>();
56
  private errorMessages: ErrorMessagesComponent;
57
  properties: EnvProperties;
58
  fundingL0;
59
  startYear;
60
  endYear;
61
  privateStakeholder = false;
62
  public keyword: FormControl;
63
  
64
  constructor(
65
    private route: ActivatedRoute,
66
    private _router: Router,
67
    private _meta: Meta,
68
    private _title: Title,
69
    private _piwikService: PiwikService,
70
    private helper: HelperService,
71
    private stakeholderService: StakeholderService,
72
    private userManagementService: UserManagementService,
73
    private statisticsService: StatisticsService,
74
    private layoutService: LayoutService,
75
    private seoService: SEOService,
76
    private cdr: ChangeDetectorRef,
77
    private sanitizer: DomSanitizer, private _fb: FormBuilder) {
78
    this.errorCodes = new ErrorCodes();
79
    this.errorMessages = new ErrorMessagesComponent();
80
    this.status = this.errorCodes.LOADING;
81
  }
82
  
83
  public ngOnInit() {
84
    this.keyword = this._fb.control('');
85
    this.keyword.valueChanges.subscribe(value => {
86
      console.log("Keyword Changed!");
87
      //TODO do a real action
88
    });
89
    this.route.data
90
      .subscribe((data: { envSpecific: EnvProperties }) => {
91
        let subscription: Subscription;
92
        this.subscriptions.push(this.userManagementService.getUserInfo().subscribe(user => {
93
          this.user = user;
94

    
95
          this.route.params.subscribe(params => {
96
            this.loading = true;
97
            this.activeTopic = null;
98
            this.activeCategory = null;
99
            this.activeSubCategory = null;
100

    
101
            if (subscription) {
102
              subscription.unsubscribe();
103
            }
104
            this.properties = data.envSpecific;
105
            var url = data.envSpecific.baseLink + this._router.url;
106
            this.route.queryParams.subscribe(params => {
107
              this.isViewPublic = (params['view'] == 'public');
108
            });
109
            this.buildMenu();
110

    
111
            if (!this.stakeholder || this.stakeholder.alias !== params['stakeholder']) {
112
              this.status = this.errorCodes.LOADING;
113
              this.numberResults = new Map<string, number>();
114
              this.chartsActiveType = new Map<string, IndicatorPath>();
115
              subscription = this.stakeholderService.getStakeholderAsObservable().subscribe(stakeholder => {
116
                if (stakeholder) {
117
                  this.stakeholder = stakeholder;
118
                  if(stakeholder.isActive && (stakeholder.isPublic || this.isAdmin())) {
119
                    this.seoService.createLinkForCanonicalURL(url, false);
120
                    this._meta.updateTag({content: url}, "property='og:url'");
121
                    var description = "Monitor Dashboard | " + this.stakeholder.index_name;
122
                    var title = "Monitor Dashboard | " + this.stakeholder.index_shortName;
123
                    this._meta.updateTag({content: description}, "name='description'");
124
                    this._meta.updateTag({content: description}, "property='og:description'");
125
                    this._meta.updateTag({content: title}, "property='og:title'");
126
                    this._title.setTitle(title);
127
                    if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
128
                      this.piwiksub = this._piwikService.trackView(this.properties, title, this.properties.piwikSiteId).subscribe();
129
                    }
130
                    //this.getDivContents();
131
                    this.getPageContents();
132
                    this.status = this.errorCodes.DONE;
133
                    this.setView(params);
134
                    this.layoutService.setOpen(true);
135
                  } else {
136
                    this.privateStakeholder = true;
137
                    // this.navigateToError();
138
                    subscription.unsubscribe();
139
                  }
140
                }
141
              });
142
              this.subscriptions.push(subscription);
143
            } else {
144
              this.setView(params);
145
            }
146
          });
147
        }));
148
      });
149
  }
150
  
151
  canExit() {
152
    if (this.sideBarItems.length > 0) {
153
      let status = [];
154
      this.sideBarItems.forEach(item => {
155
        status.push(item.open);
156
      });
157
      MonitorComponent.sidebarStatus = {
158
        id: this.activeTopic.alias,
159
        status: status
160
      };
161
    }
162
    return true;
163
  }
164
  
165
  public get open() {
166
    return this.layoutService.open;
167
  }
168
  
169
  private getPageContents() {
170
    this.helper.getPageHelpContents(this.properties, 'monitor', this._router.url).subscribe(contents => {
171
      this.pageContents = contents;
172
    })
173
  }
174
  
175
  private getDivContents() {
176
    this.helper.getDivHelpContents(this.properties, 'monitor', this._router.url).subscribe(contents => {
177
      this.divContents = contents;
178
    })
179
  }
180
  
181
  private setView(params: Params) {
182
    if (params['topic']) {
183
      this.activeTopic = this.stakeholder.topics.find(topic => topic.alias === decodeURIComponent(params['topic']) && this.isPublicOrIsMember(topic.isPublic) && topic.isActive);
184
      if (this.activeTopic) {
185
        if (params['category']) {
186
          this.activeCategory = this.activeTopic.categories.find(category =>
187
            (category.alias === params['category']) && this.isPublicOrIsMember(category.isPublic) && category.isActive);
188
          if (!this.activeCategory) {
189
            this.navigateToError();
190
            return;
191
          }
192
        } else {
193
          this.activeCategory = this.activeTopic.categories.find(category => this.isPublicOrIsMember(category.isPublic) && category.isActive);
194
          if (this.activeCategory) {
195
            this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
196
              this.isPublicOrIsMember(subCategory.isPublic) && subCategory.isActive);
197
            this.setSideBar();
198
            if (this.activeSubCategory) {
199
              this.setIndicators();
200
            }
201
          } else {
202
            this.setSideBar();
203
          }
204
          return;
205
        }
206
        if (this.activeCategory) {
207
          if (params['subCategory']) {
208
            this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
209
              (subCategory.alias === params['subCategory'] && this.isPublicOrIsMember(subCategory.isPublic) && subCategory.isActive));
210
            if (!this.activeSubCategory) {
211
              this.navigateToError();
212
              return;
213
            }
214
          } else {
215
            this.activeSubCategory = this.activeCategory.subCategories.find(subCategory =>
216
              this.isPublicOrIsMember(subCategory.isPublic) && subCategory.isActive);
217
          }
218
          if (this.activeSubCategory) {
219
            this.setSideBar();
220
            this.setIndicators();
221
          } else {
222
            this.navigateToError();
223
          }
224
          return;
225
        } else {
226
          this.activeSubCategory = null;
227
        }
228
      } else {
229
        this.navigateToError();
230
        return;
231
      }
232
    } else {
233
      this.activeTopic = this.stakeholder.topics.find(topic => this.isPublicOrIsMember(topic.isPublic) && topic.isActive);
234
      if (this.activeTopic) {
235
        this.activeCategory = this.activeTopic.categories.find(category => this.isPublicOrIsMember(category.isPublic) && category.isActive);
236
        if (this.activeCategory) {
237
          this.activeSubCategory = this.activeCategory.subCategories.find(subCategory => this.isPublicOrIsMember(subCategory.isPublic) && subCategory.isActive);
238
          if (this.activeSubCategory) {
239
            this.setSideBar();
240
            this.setIndicators();
241
          // } else {
242
            // this.navigateToError();
243
          }
244
        // } else {
245
          // this.navigateToError();
246
        }
247
      // } else {
248
        // this.navigateToError();
249
      }
250
    }
251
  }
252
  
253
  private setSideBar() {
254
    let items: MenuItem[] = [];
255
    this.stakeholder.topics.forEach((topic) => {
256
      if (this.isPublicOrIsMember(topic.isPublic) && topic.isActive) {
257
        let topicItem: MenuItem = new MenuItem(topic.alias, topic.name, "", (
258
          '/' + this.stakeholder.alias + '/' + topic.alias ),
259
          null, [], [], {});
260
         topicItem.icon = topic.icon;
261
        items.push(topicItem);
262
        }
263
    });
264
    let categoryItems: MenuItem[] = [];
265
    this.activeTopic.categories.forEach((category, index) => {
266
      if (this.isPublicOrIsMember(category.isPublic) && category.isActive) {
267
        let subItems: MenuItem[] = [];
268
        /*category.subCategories.forEach(subCategory => {
269
          if (this.isPublicOrIsMember(subCategory.isPublic) && subCategory.isActive) {
270
            subItems.push(new MenuItem(subCategory.alias, subCategory.name, "", (
271
              '/' + this.stakeholder.alias + '/' + this.activeTopic.alias + '/' + category.alias + '/' + subCategory.alias),
272
              null, null, [], {}));
273
          }
274
        });*/
275
        let open = this.activeCategory.alias === category.alias;
276
        if (MonitorComponent.sidebarStatus && MonitorComponent.sidebarStatus.id === this.activeTopic.alias) {
277
          open = MonitorComponent.sidebarStatus.status[index];
278
        }
279
        //  constructor(id: string, title: string, url: string, route: string, needsAuthorization: boolean, entitiesRequired: string[], routeRequired: string[], params) {
280
        let categoryItem: MenuItem = new MenuItem(category.alias, category.name, "", (
281
          '/' + this.stakeholder.alias + '/' + this.activeTopic.alias + '/' + category.alias),
282
          null, [], [], {});
283
        categoryItem.items = subItems;
284
        categoryItem.open = open;
285
        categoryItems.push(categoryItem);
286
      }
287
    });
288
    this.topBarItems = categoryItems;
289
    if (items.length === 0) {
290
      items.push(new MenuItem('noCategories', 'No categories available yet', "", "", false, [], [], {}));
291
    }
292
    this.sideBarItems = items;
293
    this.loading = false;
294
  }
295
  
296
  private setIndicators() {
297
    let urls: Map<string, [number, number][]> = new Map<string, [number, number][]>();
298
    this.activeSubCategory.numbers.forEach((section, i) => {
299
      section.indicators.forEach((number, j) => {
300
        if (number.isActive && this.isPublicOrIsMember(number.isPublic)) {
301
          let url = number.indicatorPaths[0].url;
302
          //add fundingLevel0 filter in the query
303
          if (this.fundingL0 && number.indicatorPaths[0].filters.get("fundingL0")) {
304
            url = url + number.indicatorPaths[0].filters.get("fundingL0").replace(ChartHelper.prefix + 'fundingL0' + ChartHelper.suffix, encodeURIComponent(this.fundingL0));
305
          }
306
          const pair = JSON.stringify([number.indicatorPaths[0].source, url]);
307
          const indexes = urls.get(pair) ? urls.get(pair) : [];
308
          indexes.push([i, j]);
309
          urls.set(pair, indexes);
310
        }
311
      });
312
    });
313
    urls.forEach((indexes, pair) => {
314
      pair = JSON.parse(pair);
315
      this.statisticsService.getNumbers(pair[0], IndicatorUtils.getNumberUrl(this.stakeholder, pair[1])).subscribe(response => {
316
        indexes.forEach(([i, j]) => {
317
          let result = JSON.parse(JSON.stringify(response));
318
          this.activeSubCategory.numbers[i].indicators[j].indicatorPaths[0].jsonPath.forEach(jsonPath => {
319
            if (result) {
320
              result = result[jsonPath];
321
            }
322
          });
323
          this.numberResults.set(i + '-' + j, result);
324
        });
325
      })
326
    });
327
    this.activeSubCategory.charts.forEach((section, i) => {
328
      section.indicators.forEach((indicator, j) => {
329
        if (indicator.indicatorPaths.length > 0) {
330
          indicator.indicatorPaths[0].safeResourceUrl = this.getUrlByStakeHolder(indicator.indicatorPaths[0]);
331
          this.chartsActiveType.set(i + '-' + j, indicator.indicatorPaths[0]);
332
        }
333
      });
334
    });
335
    this.cdr.detectChanges();
336
  }
337
  
338
  public getUrlByStakeHolder(indicatorPath: IndicatorPath) {
339
    return this.sanitizer.bypassSecurityTrustResourceUrl(
340
      this.statisticsService.getChartUrl(indicatorPath.source, this.indicatorUtils.getFullUrl(this.stakeholder, indicatorPath, this.fundingL0, this.startYear, this.endYear)));
341
  }
342
  
343
  public setActiveChart(i: number, j: number, type: string) {
344
    let activeChart = this.activeSubCategory.charts[i].indicators[j].indicatorPaths.filter(indicatorPath => indicatorPath.type === type)[0];
345
    activeChart.safeResourceUrl = this.getUrlByStakeHolder(activeChart);
346
    this.chartsActiveType.set(i + '-' + j, activeChart);
347
  }
348
  
349
  private navigateToError() {
350
    this._router.navigate(['/error'], {queryParams: {'page': this._router.url}});
351
  }
352
  
353
  public navigateTo(stakeholder: string, topic: string, category: string = null, subcategory: string = null) {
354
    let url = stakeholder + '/' + topic + ((category) ? ('/'
355
      + category) : '') + ((subcategory) ? ('/' + subcategory) : '');
356
    return this._router.navigate([url]);
357
  }
358
  
359
  public quote(param: string): string {
360
    return StringUtils.quote(param);
361
  }
362
  
363
  public ngOnDestroy() {
364
    if (this.piwiksub) {
365
      this.piwiksub.unsubscribe();
366
    }
367
  }
368
  
369
  buildMenu() {
370
    this.userMenuItems = [];
371
    // if (Session.isPortalAdministrator(this.user)) {
372
    //   this.userMenuItems.push(new MenuItem("", "Manage helptexts",
373
    //     ((this.properties.environment == "beta") ? "https://beta.admin.connect.openaire.eu" : "https://admin.explore.openaire.eu") + "/dashboard?communityId=openaire", "", true, [], [], {}))
374
    //
375
    // }
376
    if (this.user) {
377
      this.userMenuItems.push(new MenuItem("", "Manage Stakeholders", "", "/admin", false, [], [], {}));
378
    }
379
    if (this.user) {
380
      this.userMenuItems.push(new MenuItem("", "User information", "", "/user-info", false, [], [], {}));
381
    }
382
  }
383

    
384
  isAdmin(){
385
    return this.user && (Session.isPortalAdministrator(this.user) || Session.isCommunityCurator(this.user) || Session.isMonitorCurator(this.user));
386
  }
387

    
388
  isLoggedIn() {
389
    return this.user;
390
  }
391

    
392
  public isPublicOrIsMember(isPublic: boolean): boolean {
393
    if (isPublic) {
394
      return true;
395
    } else {
396
      if (this.isViewPublic) { // preview for not members
397
        return false;
398
      } else if(this.user) {
399
        // if user is member, return true
400
        return true;
401
      }
402
      return false;
403
    }
404
  }
405
}
(4-4/5)