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

    
55
  @ViewChild(ModalLoading) loading: ModalLoading;
56

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

    
66
  descending = true;
67
  sortby = "date";
68

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

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

    
79
  claimsDeleted: number = 0;
80
  @Input() communityId: string = null;
81

    
82
  url = null;
83
  public pageContents = null;
84

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

    
90
  ngOnInit() {
91

    
92
        this.properties = properties;
93
        this.url = properties.domain + properties.baseLink + this._router.url;
94

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

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

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

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

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

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

    
142
        }));
143

    
144

    
145

    
146
  }
147

    
148
  ngOnDestroy() {
149
    this.subscriptions.forEach(subscription => {
150
      if (subscription instanceof Subscriber) {
151
        subscription.unsubscribe();
152
      }
153
    });
154
  }
155

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

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

    
251

    
252
  }
253

    
254
  handleErrors(err, message) {
255

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

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

    
273
      }
274
    } catch (e) {
275

    
276
    }
277

    
278
  }
279

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

    
284
  goTo(page: number = 1) {
285

    
286
    this.page = page;
287

    
288
    this.location.go(location.pathname, this.getParametersString());
289
    this.getClaims();
290
  }
291

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

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

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

    
340
  changeSize() {
341
    this.goTo();
342
  }
343

    
344

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

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

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

    
391
  }
392

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

    
414
    this.goTo();
415
  }
416

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

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

    
457

    
458
    }
459

    
460
  }
461

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

    
475

    
476
    }
477
  }
478

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

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

    
504

    
505
  confirmOpen() {
506
    if (this.selected.length <= 0) {
507

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

    
520
  confirmClose() {
521
    this.delete();
522
  }
523

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

    
533
    }
534
    this.batchDeleteById(ids);
535
  }
536

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

    
589
        }));
590
    }
591
  }
592

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

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

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

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

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

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