Project

General

Profile

1
import {Component, Input, ViewChild} from '@angular/core';
2
import {Location} from '@angular/common';
3
import {ActivatedRoute, Router} from '@angular/router';
4
import {Subject} from 'rxjs';
5
import {debounceTime, distinctUntilChanged} from 'rxjs/operators';
6
import {ClaimsService} from '../service/claims.service';
7
import {ModalLoading} from '../../../utils/modal/loading.component';
8
import {AlertModal} from '../../../utils/modal/alert';
9
import {Session, User} from '../../../login/utils/helper.class';
10
import {EnvProperties} from '../../../utils/properties/env-properties';
11
import {LoginErrorCodes} from '../../../login/utils/guardHelper.class';
12
import {SEOService} from '../../../sharedComponents/SEO/SEO.service';
13
import {IndexInfoService} from "../../../utils/indexInfo.service";
14
import {ClaimDBRecord} from "../claimHelper.class";
15
import {Dates} from "../../../utils/string-utils.class";
16
import {HelperService} from "../../../utils/helper/helper.service";
17
import {Meta, Title} from "@angular/platform-browser";
18
import {PiwikService} from "../../../utils/piwik/piwik.service";
19
import {properties} from "../../../../../environments/environment";
20

    
21

    
22
@Component({
23
  selector: 'displayClaims',
24
  templateUrl: 'displayClaims.component.html',
25
  // providers: [ClaimsService]
26

    
27
})
28
export class DisplayClaimsComponent {
29
  @Input() piwikSiteId = null;
30
  @Input() title: string = "";
31
  piwiksub: any;
32

    
33
  properties: EnvProperties;
34
  public searchTermStream = new Subject<string>();
35
  sub: any;
36
  //string because comes as input from component directive
37
  @Input() enableDelete: boolean = false;
38
  @Input() showUserEmail: boolean = true;
39
  @Input() myClaims: boolean = false;
40
  @Input() isAdmin: boolean = false;
41
  page: number = 1;
42
  size: number = 10;
43
  sizes = [10, 20, 30, 50];
44
  keyword: string; // the keyword string to give to the request as parameter
45
  inputkeyword: string; // the string written in the input field (keyword=inputkeyword when its length is bigger than 3 and the user stops typing)
46
  types = ["All", "Project", "Context", "Result", "User"];
47
  pageLoading:boolean = false;
48
  @Input() fetchBy: string;
49
  @Input() fetchId: string;
50
  @Input() user: User;
51
  resultsNum: number;
52
  claims: ClaimDBRecord[];
53
  @Input() externalPortalUrl: string = null;
54
  @Input() claimsInfoURL: string;// ="https://www.openaire.eu/linking";
55
  lastIndexDate = null;
56

    
57
  @ViewChild(ModalLoading) loading: ModalLoading;
58

    
59
  //checkboxes:
60
  publicationCB = false;
61
  datasetCB = false;
62
  softwareCB = false;
63
  otherCB = false;
64
  contextCB = false;
65
  projectCB = false;
66
  entityTypes: string[] = [];
67

    
68
  descending = true;
69
  sortby = "date";
70

    
71
  selected = [];
72
  deleteMessage: string = "";
73
  showErrorMessage: boolean = false;
74
  showForbiddenMessage: boolean = false;
75
  userValidMessage: string = "";
76

    
77
  //params for pagingFormatter to use when navigate to page
78
  params;
79
  @ViewChild(AlertModal) alert;
80

    
81
  claimsDeleted: number = 0;
82
  @Input() communityId: string = null;
83

    
84
  url = null;
85
  public pageContents = null;
86

    
87
  constructor(private _claimService: ClaimsService, private route: ActivatedRoute, private _router: Router, private location: Location,
88
              private _meta: Meta, private _title: Title, private _piwikService: PiwikService,
89
              private seoService: SEOService, private indexInfoService: IndexInfoService, private helper: HelperService) {
90
  }
91

    
92
  ngOnInit() {
93

    
94
        this.properties = properties;
95
        this.url = properties.domain + properties.baseLink + this._router.url;
96

    
97
        var description = "Openaire, linking, claim, publication, research data, software, other research product, project, community";
98
        this.updateTitle(this.title);
99
        this.updateDescription(description);
100
        this.updateUrl(this.url);
101
        if (this.properties.enablePiwikTrack && (typeof document !== 'undefined')) {
102
          this.piwiksub = this._piwikService.trackView(this.properties, this.title, this.piwikSiteId).subscribe();
103
        }
104

    
105
        this.helper.getPageHelpContents(this.properties, this.communityId, this._router.url).subscribe(contents => {
106
          this.pageContents = contents;
107
        });
108
        this.indexInfoService.getLastIndexDate(this.properties).subscribe(res => {
109
          this.lastIndexDate = res;
110
        });
111
        this.sub = this.route.queryParams.subscribe(params => {
112
          this.seoService.createLinkForCanonicalURL(this.url, false);
113

    
114
          if (this.myClaims) {
115
            this.fetchBy = "User";
116
            this.fetchId = this.user.email;
117
          } else {
118

    
119
            this.fetchBy = (this.fetchBy) ? this.fetchBy : params['fetchBy'];
120
            this.fetchBy = (this.types.indexOf(this.fetchBy) != -1) ? this.fetchBy : 'All';
121
            this.fetchId = (this.fetchId) ? this.fetchId : params['fetchId'];
122
            this.fetchId = this.fetchId ? this.fetchId : '';
123
          }
124

    
125
          let page = (params['page'] === undefined) ? 1 : +params['page'];
126
          let size = (params['size'] === undefined) ? 10 : +params['size'];
127

    
128
          this.keyword = (params['keyword'] ? params['keyword'] : "");
129
          this.inputkeyword = this.keyword;
130
          this.page = (page <= 0) ? 1 : page;
131
          this.size = (size <= 0) ? 10 : size;
132
          this.entityTypes = [];//(params['types']?params['types']:[]);
133
          this.setTypes(params['types']); // check the appropriate checkboxes
134
          this.setSortby(params['sort']);
135
          this.getClaims();
136
          this.searchTermStream
137
            .pipe(debounceTime(300), distinctUntilChanged())
138
            .subscribe((term: string) => {
139
              this.keyword = term;
140
              this.page = 1;
141
              this.goTo();
142
            });
143

    
144
        });
145

    
146

    
147

    
148
  }
149

    
150
  ngOnDestroy() {
151
    this.sub.unsubscribe();
152
    if (this.piwiksub) {
153
      this.piwiksub.unsubscribe();
154
    }
155
    //this.searchTermStreamSub.unsubscribe();
156
  }
157

    
158
  getClaims() {
159
    if (!Session.isLoggedIn()) {
160
      this.userValidMessage = "User session has expired. Please login again.";
161
      this._router.navigate(['/user-info'], {
162
        queryParams: {
163
          "errorCode": LoginErrorCodes.NOT_VALID,
164
          "redirectUrl": this._router.url
165
        }
166
      });
167
    } else {
168
      this.selected = [];
169
      let types = '';
170
      this.showErrorMessage = false;
171
      this.showForbiddenMessage = false;
172
      for (let type of this.entityTypes) {
173
        types += (types.length > 0 ? '&' : '') + "types=" + type;
174
      }
175
      this.pageLoading = true;
176
      if (this.fetchBy == "Project") {
177
        this._claimService.getClaimsByProject(this.size, this.page, this.fetchId, this.keyword, this.sortby, this.descending, types, this.properties.claimsAPIURL).subscribe(
178
          data => {
179
            this.manageAPIData(data);
180
            this.pageLoading = false;
181
          },
182
          err => {
183
            this.handleErrors(err, "Error getting claims for project with id: " + this.fetchId);
184
          }
185
        );
186
      } else if (this.fetchBy == "User") {
187
        this._claimService.getClaimsByUser(this.size, this.page, this.fetchId, this.keyword, this.sortby, this.descending, types, this.properties.claimsAPIURL).subscribe(
188
          data => {
189
            this.manageAPIData(data);
190
            this.pageLoading = false;
191
          },
192
          err => {
193
            this.handleErrors(err, "Error getting claims for user with id: " + this.fetchId);
194
            this.pageLoading = false;
195
          }
196
        );
197
      } else if (this.fetchBy == "Result") {
198
        this._claimService.getClaimsByResult(this.size, this.page, this.fetchId, this.keyword, this.sortby, this.descending, types, this.properties.claimsAPIURL).subscribe(
199
          data => {
200
            this.manageAPIData(data);
201
            this.pageLoading = false;
202
          },
203
          err => {
204
            this.handleErrors(err, "Error getting claims for entity with id: " + this.fetchId);
205
            this.pageLoading = false;
206
          }
207
        );
208
      } else if (this.fetchBy == "Context") {
209
        this._claimService.getClaimsBycontext(this.size, this.page, this.fetchId, this.keyword, this.sortby, this.descending, types, this.properties.claimsAPIURL).subscribe(
210
          data => {
211
            this.manageAPIData(data);
212
            this.pageLoading = false;
213
          },
214
          err => {
215
            this.handleErrors(err, "Error getting claims for context with id: " + this.fetchId);
216
            this.pageLoading = false;
217
          }
218
        );
219
      } else {
220
        this._claimService.getClaims(this.size, this.page, this.keyword, this.sortby, this.descending, types, this.properties.claimsAPIURL).subscribe(
221
          data => {
222
              this.manageAPIData(data);
223
              this.pageLoading = false;
224
          },
225
          err => {
226
            this.handleErrors(err, "Error getting claims");
227
            this.pageLoading = false;
228
          }
229
        );
230
      }
231
    }
232
  }
233

    
234
  manageAPIData(data) {
235
    // let d = new Date();
236
    // let dateTomillis = d.getTime();
237
    // let millis24h: number = 24 * 3600000;
238
    // if(this.showLatestClaims && this.recentClaims.length == 0){
239
    //   this.recentClaims = [];
240
    //   for(var i=0;i<data.data.length;i++){
241
    //     var claimDate = new Date(data.data[i].date);
242
    //     var claimDateToMillis = claimDate.getTime()
243
    //     // console.log("Claim Date is:"+claimDateToMillis + " "+(dateTomillis - claimDateToMillis));
244
    //     if((dateTomillis - claimDateToMillis)<millis24h){
245
    //       // console.log("Claim in:"+  " "+(dateTomillis - claimDateToMillis)+" < " +(millis24h));
246
    //       this.recentClaims.push(data.data[i]);
247
    //     }
248
    //   }
249
    // }
250
    this.claims = data.data;
251
    this.resultsNum = data.total;
252

    
253

    
254
  }
255

    
256
  handleErrors(err, message) {
257

    
258
    this.showErrorMessage = true;
259
    console.error("Dispaly Claims (component): " + message +" " + (err && err.error?err.error:''));
260
    try {
261
      let error = err && err.error?err.error:err;
262
      if (error.code && error.code == 403) {
263
        this.showErrorMessage = false;
264
        this.showForbiddenMessage = true;
265
        if(!Session.isLoggedIn()) {
266

    
267
          this._router.navigate(['/user-info'], {
268
            queryParams: {
269
              "errorCode": LoginErrorCodes.NOT_VALID,
270
              "redirectUrl": this._router.url
271
            }
272
          });
273
        }
274

    
275
      }
276
    } catch (e) {
277

    
278
    }
279

    
280
  }
281

    
282
  // private static handleError(message: string, error) {
283
  //    console.error("Dispaly Claims (component): " + message, error);
284
  // }
285

    
286
  goTo(page: number = 1) {
287

    
288
    this.page = page;
289

    
290
    this.location.go(location.pathname, this.getParametersString());
291
    this.getClaims();
292
  }
293

    
294
  /*
295
    getParameters() {
296
      var params = {}
297
      if (this.myClaims) {
298
        params = {
299
          page: this.page,
300
          size: this.size,
301
          types: this.entityTypes,
302
          keyword: this.keyword,
303
          sort: this.getSortby()
304
        };
305
      } else {
306
        params = {
307
          page: this.page,
308
          size: this.size,
309
          types: this.entityTypes,
310
          fetchBy: this.fetchBy,
311
          fetchId: this.fetchId,
312
          keyword: this.keyword,
313
          sort: this.getSortby()
314
        };
315
      }
316
      return params;
317
    }*/
318

    
319
  getParametersString() {
320
    let params = '';
321
    params += (this.page == 1 ? "" : (params.length > 0 ? '&' : '') + "page=" + this.page);
322
    params += (this.size == 10 ? "" : (params.length > 0 ? '&' : '') + "size=" + this.size);
323
    // params+=(this.validEntityTypes==''?"":(params.length>0?'&':'')+"types="+this.validEntityTypes);
324
    let types = "";
325
    for (let type of this.entityTypes) {
326
      types += (types.length > 0 ? ',' : '') + type;
327
    }
328
    params += (types.length > 0) ? (params.length > 0 ? '&' : '') + "types=" + types : "";
329

    
330
    if (this.isAdmin) {
331
      params += (this.fetchBy == 'All' ? "" : (params.length > 0 ? '&' : '') + "fetchBy=" + this.fetchBy);
332
      params += (this.fetchId == '' ? "" : (params.length > 0 ? '&' : '') + "fetchId=" + this.fetchId);
333
    }
334
    params += (this.getSortby() == 'datedesc' ? "" : (params.length > 0 ? '&' : '') + "sort=" + this.getSortby());
335
    params += (this.keyword == '' ? "" : (params.length > 0 ? '&' : '') + "keyword=" + this.keyword);
336
    if (this.communityId != null) {
337
      params += "&communityId=" + this.communityId;
338
    }
339
    return params;
340
  }
341

    
342
  changeSize() {
343
    this.goTo();
344
  }
345

    
346

    
347
  changeOrderby(sortby: string) {
348
    if (sortby == this.sortby) {
349
      this.descending = !this.descending;
350
    } else {
351
      this.sortby = sortby;
352
      this.descending = false;
353
    }
354
    this.goTo();
355
  }
356

    
357
  setSortby(sortby: string) {
358
    if (!sortby || sortby == "datedesc") {
359
      this.descending = true;
360
      this.sortby = "date";
361
    } else if (sortby == "dateasc") {
362
      this.descending = false;
363
      this.sortby = "date";
364
    } else if (sortby == "userasc") {
365
      this.descending = false;
366
      this.sortby = "user";
367
    } else if (sortby == "userdesc") {
368
      this.descending = true;
369
      this.sortby = "user";
370
    }
371
    if (sortby == "sourceasc") {
372
      this.descending = false;
373
      this.sortby = "source";
374
    } else if (sortby == "sourcedesc") {
375
      this.descending = true;
376
      this.sortby = "source";
377
    } else if (sortby == "targetasc") {
378
      this.descending = false;
379
      this.sortby = "target";
380
    } else if (sortby == "targetdesc") {
381
      this.descending = true;
382
      this.sortby = "target";
383
    }
384
  }
385

    
386
  getSortby(): string {
387
    if (this.descending) {
388
      return this.sortby + "desc";
389
    } else {
390
      return this.sortby + "asc";
391
    }
392

    
393
  }
394

    
395
  changeType() {
396
    this.entityTypes = [];
397
    if (this.publicationCB) {
398
      this.entityTypes.push('publication');
399
    }
400
    if (this.datasetCB) {
401
      this.entityTypes.push('dataset');
402
    }
403
    if (this.softwareCB) {
404
      this.entityTypes.push('software');
405
    }
406
    if (this.otherCB) {
407
      this.entityTypes.push('other');
408
    }
409
    if (this.projectCB) {
410
      this.entityTypes.push('project');
411
    }
412
    if (this.contextCB) {
413
      this.entityTypes.push('context');
414
    }
415

    
416
    this.goTo();
417
  }
418

    
419
  setTypes(types: string) {
420
    if (!types) {
421
      return;
422
    }
423
    if (types.length > 0) {
424
      this.entityTypes = [];
425
      if (types.indexOf("publication") != -1) {
426
        this.publicationCB = true;
427
        this.entityTypes.push("publication");
428
      }
429
      if (types.indexOf("dataset") != -1) {
430
        this.datasetCB = true;
431
        this.entityTypes.push("dataset");
432
      }
433
      if (types.indexOf("software") != -1) {
434
        this.softwareCB = true;
435
        this.entityTypes.push("software");
436
      }
437
      if (types.indexOf("other") != -1) {
438
        this.otherCB = true;
439
        this.entityTypes.push("other");
440
      }
441
      if (types.indexOf("project") != -1) {
442
        this.projectCB = true;
443
        this.entityTypes.push("project");
444
      }
445
      if (types.indexOf("context") != -1) {
446
        this.contextCB = true;
447
        this.entityTypes.push("context");
448
      }
449
    }
450
    if (this.publicationCB && this.datasetCB && this.softwareCB && this.otherCB && this.contextCB && this.projectCB) {
451
      this.entityTypes = [];
452
    }
453
  }
454

    
455
  changekeyword() {
456
    if (this.inputkeyword.length >= 3 || this.inputkeyword.length == 0) {
457
      this.searchTermStream.next(this.inputkeyword);
458

    
459

    
460
    }
461

    
462
  }
463

    
464
  select(item: any, event) {
465
    this.deleteMessage = "";
466
    let value = event.currentTarget.checked;
467
    if (value) {
468
      this.selected.push(item);
469
    } else {
470
      for (var _i = 0; _i < this.selected.length; _i++) {
471
        let claim = this.selected[_i];
472
        if (claim['id'] == item.id) {
473
          this.selected.splice(_i, 1);
474
        }
475
      }
476

    
477

    
478
    }
479
  }
480

    
481
  selectAll(event) {
482
    let value = event.currentTarget.checked;
483
    if (value) {
484
      this.selected = [];
485
      for (let _i = 0; _i < this.claims.length; _i++) {
486
        let claim = this.claims[_i];
487
        this.selected.push(claim);
488
      }
489
      this.deleteMessage = "";
490
    } else {
491
      this.selected = [];
492
      this.deleteMessage = "";
493
    }
494
  }
495

    
496
  isSelected(id: string) {
497
    for (let _i = 0; _i < this.selected.length; _i++) {
498
      let claim = this.selected[_i];
499
      if (claim['id'] == id) {
500
        return true;
501
      }
502
    }
503
    return false;
504
  }
505

    
506

    
507
  confirmOpen() {
508
    if (this.selected.length <= 0) {
509

    
510
    } else {
511
      this.alert.cancelButton = true;
512
      this.alert.okButton = true;
513
      this.alert.alertTitle = "";// "Delete " + this.selected.length + " links(s)";
514
      this.alert.okButtonLeft = false;
515
      // this.alert.message = this.selected.length + " links will be deleted. Do you want to proceed? ";
516
      this.alert.okButtonText = "Delete";
517
      this.alert.cancelButtonText = "Cancel";
518
      this.alert.open();
519
    }
520
  }
521

    
522
  confirmClose() {
523
    this.delete();
524
  }
525

    
526
  delete() {
527
    this.deleteMessage = "";
528
    this.loading.open();
529
    this.claimsDeleted = 0;
530
    let ids = [];
531
    for (let i = 0; i < this.selected.length; i++) {
532
      let id = this.selected[i].id;
533
      ids.push(id);
534

    
535
    }
536
    this.batchDeleteById(ids);
537
  }
538

    
539
  batchDeleteById(ids: string[]) {
540
    if (!this.user) {
541
      this.userValidMessage = "User session has expired. Please login again.";
542
      this._router.navigate(['/user-info'], {
543
        queryParams: {
544
          "errorCode": LoginErrorCodes.NOT_VALID,
545
          "redirectUrl": this._router.url
546
        }
547
      });
548
    } else {
549
      //console.warn("Deleting claim with ids:"+ids);
550
      this._claimService.deleteBulk(ids, this.properties.claimsAPIURL).subscribe(
551
        res => {
552
          //console.info('Delete response'+res.code );
553
          //console.warn("Deleted ids:"+ res.deletedIds);
554
          //console.warn("Not found ids:"+ res.notFoundIds);
555
          //remove this claim from the
556
          let newClaims = this.claims;
557
          for (let id of res.deletedIds) {
558
            for (let _i = 0; _i < this.claims.length; _i++) {
559
              let claim = this.claims[_i];
560
              if (claim['id'] == id) {
561
                newClaims.splice(_i, 1);
562
              }
563
            }
564
            for (let _i = 0; _i < this.selected.length; _i++) {
565
              let claim = this.selected[_i];
566
              if (claim['id'] == id) {
567
                this.selected.splice(_i, 1);
568
              }
569
            }
570
          }
571
          this.claims = newClaims;
572
          this.resultsNum = this.resultsNum - res.deletedIds.length;
573
          this.loading.close();
574
          if (res.deletedIds.length > 0) {
575
            this.deleteMessage = this.deleteMessage + '<div class = "uk-alert uk-alert-primary " >' + res.deletedIds.length + ' link(s) successfully deleted.</div>';
576
          }
577
          if (res.notFoundIds.length > 0) {
578
            this.deleteMessage = this.deleteMessage + '<div class = "uk-alert uk-alert-warning " >' + res.notFoundIds.length + ' link(s) couldn\'t be deleted.</div>';
579
          }
580
          let goToPage = this.page;
581
          if (this.totalPages(this.resultsNum) < this.page && this.page > 0) {
582
            goToPage = this.page - 1;
583
          }
584
          this.goTo(goToPage);
585
        }, err => {
586
          //console.log(err);
587
          this.handleErrors(err,"Error deleting claims with ids: " + ids);
588
          this.showErrorMessage = true;
589
          this.loading.close();
590

    
591
        });
592
    }
593
  }
594

    
595
  pageChange($event) {
596
    let page: number = +$event.value;
597
    this.goTo(page);
598
  }
599

    
600
  isClaimAvailable(claim: ClaimDBRecord): boolean {
601
    //claim.target.collectedFrom == "infrastruct_::openaire" &&
602
    let lastUpdateDate = new Date((this.lastIndexDate != null) ? this.lastIndexDate : this.properties.lastIndexUpdate);
603
    let lastUpdateDateStr = Dates.getDateToString(lastUpdateDate);
604
    let claimDate = new Date(claim.date);
605
    let claimDateStr = Dates.getDateToString(claimDate);
606
    if (claimDateStr < lastUpdateDateStr) {
607
      return true;
608
    } else {
609
      if (claim.target.collectedFrom != "infrastruct_::openaire" && claim.indexed) {
610
        //  check if direct index succeded
611
        return true
612
      }
613
    }
614
    return false;
615
  }
616

    
617
  totalPages(totalResults: number): number {
618
    let totalPages: any = totalResults / (this.size);
619
    if (!(Number.isInteger(totalPages))) {
620
      totalPages = (parseInt(totalPages, 10) + 1);
621
    }
622
    return totalPages;
623
  }
624

    
625
  private updateDescription(description: string) {
626
    this._meta.updateTag({content: description}, "name='description'");
627
    this._meta.updateTag({content: description}, "property='og:description'");
628
  }
629

    
630
  private updateTitle(title: string) {
631
    var _prefix = "";
632
    if (!this.communityId) {
633
      _prefix = "OpenAIRE | ";
634
    }
635
    var _title = _prefix + ((title.length > 50) ? title.substring(0, 50) : title);
636
    this._title.setTitle(_title);
637
    this._meta.updateTag({content: _title}, "property='og:title'");
638
  }
639

    
640
  private updateUrl(url: string) {
641
    this._meta.updateTag({content: url}, "property='og:url'");
642
  }
643
}
(2-2/3)