Project

General

Profile

1
import {ChangeDetectorRef, Component, Input, ViewChild} from '@angular/core';
2
import {ActivatedRoute, Router} from '@angular/router';
3
import {Meta, Title} from '@angular/platform-browser';
4

    
5
import {EnvProperties} from '../../utils/properties/env-properties';
6
import {Id, ResultLandingInfo} from '../../utils/entities/resultLandingInfo';
7
import {RouterHelper} from '../../utils/routerHelper.class';
8

    
9
import {PiwikService} from '../../utils/piwik/piwik.service';
10
import {ResultLandingService} from './resultLanding.service';
11
import {SEOService} from '../../sharedComponents/SEO/SEO.service';
12
import {HelperFunctions} from '../../utils/HelperFunctions.class';
13
import {HelperService} from '../../utils/helper/helper.service';
14
import {Location} from "@angular/common";
15
import {MetricsService} from "../../services/metrics.service";
16
import {Organization, RelationResult, ResultPreview} from "../../utils/result-preview/result-preview";
17

    
18

    
19
@Component({
20
  selector: 'result-landing',
21
  templateUrl: 'resultLanding.component.html',
22
})
23
export class ResultLandingComponent {
24
  @Input() type: string = "publication";
25
  @Input() piwikSiteId = null;
26
  @Input() communityId = null;
27

    
28
  // Active tab variable for responsiveness
29
  @Input() activeTab: string = "References";
30

    
31
  @ViewChild('AlertModalDeletedByInference') alertModalDeletedByInference;
32
  @ViewChild('referencesModal') referencesModal;
33
  @ViewChild('bioentitiesModal') bioentitiesModal;
34
  @ViewChild('relationModal') relationModal;
35
  @ViewChild('organizationModal') organizationModal;
36
  public deleteByInferenceOpened: boolean = false;
37

    
38
  public resultLandingInfo: ResultLandingInfo;
39
  public relationResults: RelationResult[];
40
  public relation: string = 'trust';
41
  public id: string;
42
  public title: string;
43

    
44
  // Links for SEO
45
  public linkToLandingPage: string = null;
46
  public linkToSearchPage: string = null;
47

    
48
  public thresholdDescription: number = 670;
49
  public showNumDescription: number = 670;
50

    
51
  // Metrics tab variables
52
  public metricsClicked: boolean;
53
  public hasAltMetrics: boolean = false;
54
  public viewsFrameUrl: string;
55
  public downloadsFrameUrl: string;
56
  public totalViews: number;
57
  public totalDownloads: number;
58
  public pageViews: number;
59

    
60
  // Custom tab paging variables
61
  public referencesPage: number = 1;
62
  public bioentitiesPage: number = 1;
63
  public relationPage: number = 1;
64
  public organizationsPage: number = 1;
65
  public softwarePage: number = 1;
66
  public openCitationsPage: number = 1;
67
  public pageSize: number = 10;
68

    
69
  // Map counting variables
70
  public bioentitiesNum: number = 0;
71

    
72
  // Message variables
73
  public warningMessage = "";
74
  public errorMessage = "";
75
  public showLoading: boolean = true;
76

    
77
  public routerHelper: RouterHelper = new RouterHelper();
78

    
79
  private doi: string;
80
  public doiURL: string;
81
  sub: any;
82
  piwiksub: any;
83
  infoSub: any;
84
  properties: EnvProperties;
85
  public indexUpdateDate: Date;
86
  public pageContents = null;
87
  public divContents = null;
88
  
89
  public addThis: boolean = true;
90
  public showFeedback: boolean = false;
91
  public feedbackFields: string [] = [
92
    'Title', 'Authors', 'Access rights',
93
    'Publisher information', 'Funding Information',
94
    'Persistent identifiers','Other'];
95

    
96
  constructor(private _resultLaningService: ResultLandingService,
97
              private _piwikService: PiwikService,
98
              private route: ActivatedRoute,
99
              private router: Router,
100
              private _meta: Meta,
101
              private _title: Title,
102
              private _router: Router,
103
              private helper: HelperService,
104
              private seoService: SEOService,
105
              private metricsService: MetricsService,
106
              private cdr: ChangeDetectorRef,
107
              private _location: Location) {
108
  }
109

    
110
  ngOnInit() {
111
    this.route.data
112
      .subscribe((data: { envSpecific: EnvProperties }) => {
113
        this.properties = data.envSpecific;
114
        if(this.properties.lastIndexUpdate) {
115
          this.indexUpdateDate = new Date(this.properties.lastIndexUpdate);
116
        }
117
        //this.getDivContents();
118
        this.getPageContents();
119
        this.doiURL = this.properties.doiURL;
120
        this.updateUrl(data.envSpecific.baseLink + this._router.url);
121
        this.sub = this.route.queryParams.subscribe(data => {
122
          this.resultLandingInfo = null;
123
          if(this.type == "publication") {
124
            this.updateTitle("Publication");
125
            this.linkToLandingPage = this.properties.searchLinkToPublication;
126
            this.linkToSearchPage = this.properties.searchLinkToPublications;
127
            this.id = data['articleId'];
128
            this.title = "Publication";
129
          } else if(this.type == "dataset") {
130
            this.updateTitle("Dataset");
131
            this.linkToLandingPage = this.properties.searchLinkToDataset;
132
            this.linkToSearchPage = this.properties.searchLinkToDatasets;
133
            this.id = data['datasetId'];
134
            this.title = "Research Data";
135
          } else if(this.type == "software") {
136
            this.updateTitle("Software");
137
            this.linkToLandingPage = this.properties.searchLinkToSoftware;
138
            this.linkToSearchPage = this.properties.searchLinkToSoftwareLanding;
139
            this.id = data['softwareId'];
140
            this.title = "Software";
141
          } else if(this.type == "orp") {
142
            this.updateTitle("Other Research Product");
143
            this.linkToLandingPage = this.properties.searchLinkToOrp;
144
            this.linkToSearchPage = this.properties.searchLinkToOrps;
145
            this.id = data['orpId'];
146
            this.title = "Other Research Product";
147
          }else if(this.type == "result"){
148
            this.id = data["id"];
149
            this.updateTitle("Research Result");
150
            this.linkToLandingPage = this.properties.searchLinkToOrp;
151
            this.linkToSearchPage = this.properties.searchLinkToResults;
152
            this.title = "Research Result";
153
          }
154
          this.updateDescription("");
155

    
156
          this.metricsClicked = false;
157

    
158
          if (this.id) {
159
            this.getProvenanceVocabularyAndResultLandingInfo();
160
          } else {
161
            this.showLoading = false;
162

    
163
            this._router.navigate(['/error'], {queryParams: {"page": this._location.path(true), "page_type": this.type}});
164
            /*
165
            this.warningMessage = "No valid ";
166
            if(this.type == "publication" || this.type == "software") {
167
              this.warningMessage += this.type + " ";
168
            } else if(this.type == "dataset") {
169
              this.warningMessage += "research data ";
170
            } else if(this.type == "orp") {
171
              this.warningMessage += "other research product ";
172
            }
173
            this.warningMessage += "id";
174
            */
175
          }
176

    
177
          this.viewsFrameUrl = this.properties.framesAPIURL + 'merge.php?com=query&data=[{"query":"resRepoViews", "resTitle":"' + this.id + '", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":80,"sort":"xaxis","xStyle":{"r":-30,"s":"6","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly views"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false';
178
          this.downloadsFrameUrl = this.properties.framesAPIURL + 'merge.php?com=query&data=[{"query":"resRepoDownloads", "resTitle":"' + this.id + '", "table":"","fields":[{"fld":"sum","agg":"sum","type":"column","yaxis":1,"c":false}],"xaxis":{"name":"month","agg":"sum"},"group":" ","color":"","type":"chart","size":80,"sort":"xaxis","xStyle":{"r":-30,"s":"6","l":"-","ft":"-","wt":"-"},"title":"","subtitle":"","xaxistitle":"Repository","yaxisheaders":["Monthly downloads"],"generalxaxis":"","theme":0,"in":[],"filters":[{"name":"","values":[""],"to":"-1"}]}]&info_types=["column"]&stacking=normal&steps=false&fontFamily=Courier&spacing=[5,0,0,0]&style=[{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"rgba(0, 0, 0, 1)","size":"18"},{"color":"000000","size":""},{"color":"000000","size":""}]&backgroundColor=rgba(255,255,255,1)&colors[]=rgba(67, 67, 72, 1)&colors[]=rgba(144, 237, 125, 1)&colors[]=rgba(247, 163, 92, 1)&colors[]=rgba(128, 133, 233, 1)&colors[]=rgba(241, 92, 128, 1)&colors[]=rgba(228, 211, 84, 1)&colors[]=rgba(43, 144, 143, 1)&colors[]=rgba(244, 91, 91, 1)&colors[]=rgba(145, 232, 225, 1)&xlinew=0&ylinew=1&legends=true&tooltips=true&persistent=false';
179

    
180
          this.scroll();
181
        });
182
      });
183
  }
184

    
185
  private getPageContents() {
186
    this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
187
      this.pageContents = contents;
188
    });
189
  }
190

    
191
  private getDivContents() {
192
    this.helper.getDivHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
193
      this.divContents = contents;
194
    });
195
  }
196

    
197
  ngOnDestroy() {
198
    if (this.sub) {
199
      this.sub.unsubscribe();
200
    }
201
    if (this.piwiksub) {
202
      this.piwiksub.unsubscribe();
203
    }
204
    if (this.infoSub) {
205
      this.infoSub.unsubscribe();
206
    }
207
  }
208
  
209
  public getTypeName(): string {
210
    if (this.type === "dataset") {
211
      return "research data";
212
    } else if (this.type === "orp" || this.type === "other") {
213
      return "other research product";
214
    } else {
215
      return this.type;
216
    }
217
  }
218
  
219
  public removeUnknown(array: string[], type: boolean = false): string[] {
220
    if (type) {
221
      return this.removeDuplicates(array).filter(value => value.toLowerCase() !== 'unknown');
222
    } else {
223
      return array.filter(value => value.toLowerCase() !== 'unknown');
224
    }
225
  }
226
  
227
  public removeDuplicates(array: string[]): string[] {
228
    let type = this.getTypeName();
229
    return array.filter(value => value.toLowerCase() !== type);
230
  }
231

    
232
  private getOpenCitations() {
233
    this._resultLaningService.getOpenCitations(this.id, this.properties).subscribe(
234
      data => {
235
        this.resultLandingInfo.openCitations = data[1];
236
      },
237
      err => {
238
        this.handleError("Error getting open citation for "+this.type+" with id: " + this.id, err);
239
      }
240
    );
241
  }
242

    
243
  private getProvenanceVocabularyAndResultLandingInfo() {
244
    this.warningMessage = '';
245
    this.errorMessage = '';
246
    this.showLoading = true;
247

    
248
    this.resultLandingInfo = null;
249

    
250
    this._resultLaningService.getProvenanceActionVocabulary(this.properties).subscribe(
251
      provenanceActionVocabulary => {
252
        this.getResultLandingInfo(provenanceActionVocabulary);
253
      }, err => {
254
        this.getResultLandingInfo(null);
255
        this.handleError("Error getting provenance action vocabulary for "+this.type+" with id: " + this.id, err);
256
      }
257
    );
258

    
259
  }
260

    
261
  private getResultLandingInfo(provenanceActionVocabulary: any) {
262
    this.infoSub = this._resultLaningService.getResultLandingInfo(this.id, this.type, provenanceActionVocabulary, this.properties).subscribe(
263
      data => {
264
        this.resultLandingInfo = data;
265
        if(this.type == "result"){ // no type was specified - update URL based this.resultLandingInfo.resultType
266
          this.updateUrlWithType();
267
        }
268
        this.seoService.createLinkForCanonicalURL(this.properties.baseLink + this.linkToLandingPage + this.resultLandingInfo.record["result"]["header"]["dri:objIdentifier"]);
269
        if ((this.type == "publication") && (this.properties.environment == "beta" || this.properties.environment == "development") && (typeof document !== 'undefined')) {
270
          this.getOpenCitations();
271
        }
272

    
273
        if (this.resultLandingInfo.title) {
274
          this.updateTitle(this.resultLandingInfo.title);
275
          this.updateDescription((this.resultLandingInfo.description ? (this.resultLandingInfo.description) : ("," + this.resultLandingInfo.title)));
276
        }
277
        if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
278
          this.piwiksub = this._piwikService.trackView(this.properties, this.resultLandingInfo.title/*.name*/, this.piwikSiteId).subscribe();
279
        }
280

    
281
        let bioentitiesNum = 0;
282
        if (this.resultLandingInfo.bioentities != undefined) {
283
          this.resultLandingInfo.bioentities.forEach(function (value, key, map) {
284
            bioentitiesNum += value.size;
285
          });
286
        }
287
        this.bioentitiesNum = bioentitiesNum;
288
        if (this.resultLandingInfo.identifiers != undefined && this.resultLandingInfo.identifiers.has('doi')) {
289
          this.doi = this.resultLandingInfo.identifiers.get('doi')[0];
290
          this.metricsService.hasAltMetrics(this.properties.altMetricsAPIURL, this.doi).subscribe(hasAltMetrics => {
291
            this.hasAltMetrics = hasAltMetrics;
292
          }, error => {
293
            this.hasAltMetrics = false;
294
          });
295
        }
296
        this.showLoading = false;
297
        if (this.resultLandingInfo.references) {
298
          this.activeTab = "References";
299
        } else if (this.resultLandingInfo.relatedResearchResults) {
300
          this.activeTab = "Related Research Results";
301
        } else if (this.resultLandingInfo.similarResearchResults) {
302
          this.activeTab = "Similar Research Results";
303
        } else if (this.resultLandingInfo.organizations) {
304
          this.activeTab = "Related Organizations";
305
        } else if (this.resultLandingInfo.bioentities) {
306
          this.activeTab = "Bioentities";
307
        } else {
308
          this.activeTab = "Metrics";
309
          //this.metricsClicked = true;
310
        }
311
      },
312
      err => {
313
        this.handleError("Error getting "+this.type+" for id: " + this.id, err);
314

    
315
        if(err.status == 404) {
316
          this._router.navigate(['/error'], {queryParams: {"page": this._location.path(true), "page_type": this.type}});
317
        }
318

    
319
        if(this.type == "publication" || this.type == "software") {
320
          this.errorMessage = 'No '+this.type+' found';
321
        } else if(this.type == "dataset") {
322
          this.errorMessage += "No research data found";
323
        } else if(this.type == "orp") {
324
          this.errorMessage += "No research product found";
325
        }
326
        this.showLoading = false;
327
        this.seoService.createLinkForCanonicalURL(this.properties.baseLink + this.linkToSearchPage);
328
      }
329
    );
330
  }
331

    
332
  public metricsResults($event) {
333
    this.totalViews = $event.totalViews;
334
    this.totalDownloads = $event.totalDownloads;
335
    this.pageViews = $event.pageViews;
336
  }
337
  
338
  public get hasMetrics(): boolean {
339
    return !(this.totalViews && this.totalDownloads && this.pageViews) || this.totalViews > 0 || this.totalDownloads > 0||this.pageViews > 0;
340
  }
341

    
342
  public buildCurationTooltip(): string {
343
    let tooltipContent: string = "<div class='uk-margin uk-padding-small'>";
344

    
345
    tooltipContent += "<h4>Record in preview</h4>";
346
    tooltipContent += "<p>Bibliographic record accepted by the system, but not yet processed by <br> OpenAIRE tools for information quality improvement and de-duplication</p>";
347

    
348
    tooltipContent += "</div>";
349
    return tooltipContent;
350
  }
351

    
352
  private updateDescription(description: string) {
353
    this._meta.updateTag({content: description.substring(0, 160)}, "name='description'");
354
    this._meta.updateTag({content: description.substring(0, 160)}, "property='og:description'");
355
  }
356

    
357
  private updateTitle(title: string) {
358
    var _prefix = "";
359
    // if(!this.communityId) {
360
    //   _prefix = "OpenAIRE | ";
361
    // }
362
    // var _title = _prefix + ((title.length > 50) ? title.substring(0, 50) : title);
363
    this._title.setTitle(title);
364
    this._meta.updateTag({content: title}, "property='og:title'");
365
  }
366

    
367
  private updateUrl(url: string) {
368
    this._meta.updateTag({content: url}, "property='og:url'");
369
  }
370

    
371
  public totalPages(totalResults: number): number {
372
    let totalPages: any = totalResults / this.pageSize;
373
    if (!(Number.isInteger(totalPages))) {
374
      totalPages = (parseInt(totalPages, this.pageSize) + 1);
375
    }
376
    return totalPages;
377
  }
378

    
379
  public updateReferencesPage($event) {
380
    this.referencesPage = $event.value;
381
  }
382
  
383
  public updateBioentitiesPage($event) {
384
    this.bioentitiesPage = $event.value;
385
  }
386
  
387
  public updateRelationPage($event) {
388
    this.relationPage = $event.value;
389
  }
390

    
391
  public updateOrganizationsPage($event) {
392
    this.organizationsPage = $event.value;
393
  }
394

    
395
  public updateSoftwarePage($event) {
396
    this.softwarePage = $event.value;
397
  }
398

    
399
  public updateOpenCitationsPage($event) {
400
    this.openCitationsPage = $event.value;
401
  }
402
  
403
  public accessClass(accessMode: string): string {
404
    if(accessMode.toLowerCase().indexOf('open') !== -1) {
405
      return 'open';
406
    } else if(accessMode.toLowerCase() === 'not available') {
407
      return 'unknown';
408
    } else {
409
      return 'closed';
410
    }
411
  }
412

    
413
  public keysToArray(bioentities: Map<string, string>): string[] {
414
    let keys: string[] = [];
415
    bioentities.forEach(function (value, key, map) {
416
      keys.push(key);
417
    });
418
    return keys;
419
  }
420

    
421
  public getKeys(map) {
422
    return Array.from(map.keys());
423
  }
424

    
425
  public scroll() {
426
    HelperFunctions.scroll();
427
  }
428

    
429
  private handleError(message: string, error) {
430
    if(this.type == "publication") {
431
      console.error("Publication Landing Page: " + message, error);
432
    } else if(this.type == "dataset") {
433
      console.error("Research Data Landing Page: " + message, error);
434
    } else if(this.type == "software") {
435
      console.error("Software Landing Page: " + message, error);
436
    } else if(this.type == "orp") {
437
      console.error("Other Research Product Landing Page: " + message, error);
438
    } else {
439
      console.error("Landing Page: " + message, error);
440
    }
441
  }
442

    
443
  isRouteAvailable(routeToCheck: string) {
444
    for (let i = 0; i < this.router.config.length; i++) {
445
      let routePath: string = this.router.config[i].path;
446
      if (routePath == routeToCheck) {
447
        return true;
448
      }
449
    }
450
    return false;
451
  }
452

    
453
  openDeletedByInference() {
454
    this.deleteByInferenceOpened = true;
455
    this.alertModalDeletedByInference.cancelButton = false;
456
    this.alertModalDeletedByInference.okButton = false;
457
    this.alertModalDeletedByInference.alertTitle = "Other versions of";
458
    this.alertModalDeletedByInference.open();
459
  }
460
  
461
  openReferences() {
462
    this.referencesModal.cancelButton = false;
463
    this.referencesModal.okButton = false;
464
    this.referencesModal.alertTitle = "References of";
465
    this.referencesPage = 1;
466
    this.referencesModal.open();
467
  }
468
  
469
  openBioentities() {
470
    this.bioentitiesModal.cancelButton = false;
471
    this.bioentitiesModal.okButton = false;
472
    this.bioentitiesModal.alertTitle = "Bioentities of";
473
    this.bioentitiesPage = 1;
474
    this.bioentitiesModal.open();
475
  }
476
  
477
  openRelationResults(title: string, relationResults: RelationResult[], relation: string = 'trust') {
478
    this.relationResults = relationResults;
479
    this.relation = relation;
480
    this.relationModal.cancelButton = false;
481
    this.relationModal.okButton = false;
482
    this.relationModal.alertTitle = title;
483
    this.relationPage = 1;
484
    this.relationModal.open();
485
  }
486
  
487
  openOrganizations() {
488
    this.relation = 'trust';
489
    this.organizationModal.cancelButton = false;
490
    this.organizationModal.okButton = false;
491
    this.organizationModal.alertTitle = 'Related organizations of';
492
    this.organizationsPage = 1;
493
    this.organizationModal.open();
494
  }
495
  
496
  public getResultPreview(result: RelationResult): ResultPreview {
497
    return ResultPreview.relationResultConvert(result, this.relation);
498
  }
499
  
500
  public getResultPreviewFromOrg(result: Organization): ResultPreview {
501
    return ResultPreview.organizationConvert(result, this.relation);
502
  }
503
  
504
  public hideAddThis(value: boolean) {
505
    this.addThis = value;
506
    this.cdr.detectChanges();
507
  }
508
  
509
  updateUrlWithType(){
510
    this.type = this.resultLandingInfo.resultType;
511
    if(this.type == "publication") {
512
      this._location.go("test");
513
      this.linkToLandingPage = this.properties.searchLinkToPublication;
514
      this.linkToSearchPage = this.properties.searchLinkToPublications;
515
    } else if(this.type == "dataset") {
516
      this.linkToLandingPage = this.properties.searchLinkToDataset;
517
      this.linkToSearchPage = this.properties.searchLinkToDatasets;
518
    } else if(this.type == "software") {
519
      this.linkToLandingPage = this.properties.searchLinkToSoftwareLanding;
520
      this.linkToSearchPage = this.properties.searchLinkToSoftware;
521
    } else if(this.type == "other") {
522
      this.type="orp";
523
      this.linkToLandingPage = this.properties.searchLinkToOrp;
524
      this.linkToSearchPage = this.properties.searchLinkToOrps;
525
    }
526
    this._location.go(this.linkToLandingPage + this.id);
527
  }
528
  
529
  public getReferenceUrl(id: Id): string {
530
    if(id.type === "doi") {
531
      return this.properties.doiURL + id.value;
532
    } else if(id.type === "pmc") {
533
      return this.properties.pmcURL + id.value;
534
    } else if(id.type === "pmid") {
535
      return this.properties.pmidURL + id.value;
536
    } else if(id.type === "handle") {
537
      return this.properties.handleURL + id.value;
538
    } else {
539
      return  null;
540
    }
541
  }
542
  
543
  public getReferenceIdName(id: Id): string {
544
    if(id.type === "doi") {
545
      return 'DOI'
546
    } else if(id.type === "pmc") {
547
      return 'Europe PMC'
548
    } else if(id.type === "pmid") {
549
      return 'PubMed';
550
    } else if(id.type === "handle") {
551
      return 'Handle.NET';
552
    } else {
553
      return  null;
554
    }
555
  }
556
}
(2-2/4)