Project

General

Profile

1
import {Component, Input}                 from '@angular/core';
2
import {ViewChild, Output}                from '@angular/core';
3
import {EventEmitter, ViewEncapsulation}  from '@angular/core';
4
import {OnInit, AfterViewInit}            from '@angular/core';
5
import {Location}                         from '@angular/common';
6
import {ActivatedRoute}                   from '@angular/router';
7
import {Title, Meta}                      from '@angular/platform-browser';
8

    
9
import {Observable}                       from 'rxjs/Observable';
10
import {Subject}                          from 'rxjs/Subject';
11

    
12
import {DataTableDirective }              from 'angular-datatables';
13

    
14
import {EnvProperties}                    from '../../utils/properties/env-properties';
15

    
16
import {Filter, Value}                    from './searchHelperClasses.class';
17
import {SearchResult}                     from '../../utils/entities/searchResult';
18
import {SearchFields, FieldDetails}       from '../../utils/properties/searchFields';
19
import {SearchUtilsClass}                 from './searchUtils.class';
20
import {DOI, StringUtils}                 from '../../utils/string-utils.class';
21
import {ModalLoading}                     from '../../utils/modal/loading.component';
22
import {SearchFilterComponent}            from './searchFilter.component';
23
import {SearchFilterModalComponent}       from './searchFilterModal.component';
24
import {ErrorCodes}                       from '../../utils/properties/errorCodes';
25
import {PiwikService}                     from '../../utils/piwik/piwik.service';
26
//import {SearchDataprovidersService} from '../../services/searchDataproviders.service';
27

    
28
@Component({
29
    selector: 'search-page-table',
30
    templateUrl:'searchPageTableView.component.html',
31
    styles: [`
32
      #dpTable_info, #dpTable_paginate,  #dpTable_length,  #dpTable_filter{
33
        display: none;
34
      }
35

    
36
      `],
37
      encapsulation: ViewEncapsulation.None // this used in order styles to work
38

    
39
  })
40
export class SearchPageTableViewComponent  implements OnInit, AfterViewInit {
41
  @Input() piwikSiteId = null;
42
  @Input() pageTitle = "";
43
  @Input() results;
44
  @Input() filters = [];
45
  @Input() columnNames = [];
46
  @Input() type:string = "";
47
  @Input() entityType: string = "";
48
  @Input() searchUtils:SearchUtilsClass;// = new SearchUtilsClass();
49
  //@Output() downloadClick = new EventEmitter();
50
  @Input() showResultCount:boolean = true;
51
  @Input() showRefine:boolean = true;
52
  @Input() refineFields = [];
53
  //@Input() csvParams: string;
54
  //@Input() csvPath: string;
55
  @Input() openaireLink: string;
56
  @Input() searchViewLink: string;
57
  @Input() disableForms: boolean = false;
58
  @Input() enableSearchView: boolean = true;
59
  @Input() searchFormClass: string = "searchForm";
60
  @Input() formPlaceholderText = "Type Keywords...";
61
  @ViewChild (ModalLoading) loading : ModalLoading ;
62
  private searchFieldsHelper:SearchFields = new SearchFields();
63
  private queryParameters: Map<string, string>  = new Map<string,string>();
64
  public countFilters= 0;
65
  public parameterNames:string[] =[];
66
  public parameterValues:string[] =[];
67

    
68
  public rowsOnPage:number  = 10;
69
  public isPiwikEnabled;
70

    
71

    
72
  @ViewChild (SearchFilterModalComponent) searchFilterModal : SearchFilterModalComponent ;
73
  public currentFilter: Filter;
74
  public errorCodes:ErrorCodes = new ErrorCodes();
75
  piwiksub: any;
76
  dtOptions: DataTables.Settings = {};
77
  showTable = false; filteringAdded = false;
78
  @ViewChild(DataTableDirective) datatableElement: DataTableDirective;
79
  dtTrigger: Subject<any> = new Subject(); //necessary
80

    
81
  constructor (private route: ActivatedRoute,
82
               private location: Location,
83
               private _meta: Meta,
84
               private _title: Title,
85
               private _piwikService:PiwikService) { }
86

    
87
  ngOnInit() {
88
    this.route.data
89
      .subscribe((data: { envSpecific: EnvProperties }) => {
90

    
91

    
92
        this.isPiwikEnabled = data.envSpecific.enablePiwikTrack;
93
        if(typeof window !== 'undefined') {
94
          this.updateUrl(data.envSpecific.baseLink+location.pathname);
95
        }
96
        if(typeof document !== 'undefined' && this.isPiwikEnabled){
97
          this.piwiksub = this._piwikService.trackView(data.envSpecific, this.pageTitle, this.piwikSiteId).subscribe();
98
        }
99
      });
100
        this.dtOptions = {
101
          "paging": true,
102
          "searching": false,
103
          "lengthChange": false,
104
          "pageLength": this.rowsOnPage
105
        };
106
        this.updateTitle(this.pageTitle);
107
        var description = "Openaire, search, repositories, open access, type, content provider, funder, project, " + this.type + "," +this.pageTitle;
108
        this.updateDescription(description);
109

    
110
   }
111
  ngOnDestroy() {
112
     if(this.piwiksub){
113
        this.piwiksub.unsubscribe();
114
      }
115

    
116
  }
117
    ngAfterViewInit(): void {
118
       $.fn['dataTable'].ext.search.push((settings, data, dataIndex) => {
119

    
120
          if (this.filterData(data, this.searchUtils.keyword, this.filters)) {
121
            return true;
122
          }
123
          return false;
124
        });
125

    
126

    
127
    }
128

    
129

    
130
  totalPages(): number {
131
      let totalPages:any = this.searchUtils.totalResults/(this.rowsOnPage);
132
      if(!(Number.isInteger(totalPages))) {
133
          totalPages = (parseInt(totalPages, 10) + 1);
134
      }
135
      return totalPages;
136
  }
137

    
138
  toggleModal($event) {
139
    this.currentFilter = $event.value;
140
    this.searchFilterModal.open();
141

    
142
  }
143

    
144
  updateDescription(description:string) {
145
    this._meta.updateTag({content:description},"name='description'");
146
    this._meta.updateTag({content:description},"property='og:description'");
147
  }
148
  updateTitle(title:string) {
149
    var _prefix ="OpenAIRE | ";
150
    var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title);
151
    this._title.setTitle(_title);
152
    this._meta.updateTag({content:_title},"property='og:title'");
153
  }
154
  updateUrl(url:string) {
155
    this._meta.updateTag({content:url},"property='og:url'");
156
  }
157

    
158
public getParametersFromUrl(params) {
159
  for(var i=0; i< this.refineFields.length ; i++) {
160
    var filterId =  this.refineFields[i];
161
    if(params[filterId] != undefined) {
162
      if(this.queryParameters == undefined){
163
        this.queryParameters = new Map<string,string>();
164
      }
165
      this.queryParameters[filterId]=decodeURIComponent(params[filterId]);
166
    }
167
  }
168
}
169
 /*
170
 * Mark as check the new filters that are selected, when you get them from search
171
 */
172
  public checkSelectedFilters(filters:Filter[]){
173

    
174
    this.filters = filters;
175
       for(var i=0; i< filters.length ; i++){
176
            var filter:Filter = filters[i];
177
            filter.countSelectedValues = 0;
178

    
179
              if(this.queryParameters[filter.filterId] != undefined) {
180
                let values = (decodeURIComponent(this.queryParameters[filter.filterId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1);
181
                     for(let filterValue of filter.values) {
182
                       if(values.indexOf(StringUtils.quote(filterValue.id)) > -1) {
183
                            filterValue.selected = true;
184
                            filter.countSelectedValues++;
185
                         }else{
186
                           filterValue.selected = false;
187
                         }
188
                    }
189
            }else{
190
              for(let filterValue of filter.values) {
191
                 filterValue.selected = false;
192
              }
193
            }
194
        }
195

    
196
        return filters;
197
  }
198

    
199
  /*
200
  *
201
  */
202
  private createUrlParameters(filters:Filter[], includePage:boolean){
203
    var allLimits="";//location.search.slice(1);
204
    this.parameterNames.splice(0,this.parameterNames.length);
205
    this.parameterValues.splice(0,this.parameterValues.length);
206

    
207
    for (let filter of filters){
208
      var filterLimits="";
209
      if(filter.countSelectedValues > 0){
210
        for (let value of filter.values){
211
          if(value.selected == true){
212
            filterLimits+=((filterLimits.length == 0)?'':',') +'"'+ StringUtils.URIEncode(value.id)+'"';
213
           }
214
        }
215
        this.queryParameters[filter.filterId]=filterLimits;
216
        if(filterLimits.length > 0){
217
          this.parameterNames.push(filter.filterId);
218
          this.parameterValues.push(filterLimits);
219
        }
220
        allLimits+=(allLimits.length==0?"?":"&")+((filterLimits.length == 0 )?'':filter.filterId + '='+ filterLimits) ;
221
      }
222
    }
223
    if(this.searchUtils.keyword.length > 0 ){
224
       allLimits+=(allLimits.length==0?"?":"&")+'keyword=' + this.searchUtils.keyword;
225
      this.parameterNames.push("keyword");
226
      this.parameterValues.push(this.searchUtils.keyword);
227
     }
228

    
229
    return allLimits;
230
  }
231

    
232
  public isFiltered(){
233
    var filtered=false;
234
    for (let filter of this.filters){
235
       if(filter.countSelectedValues > 0){
236
           filtered = true;
237
           break;
238
       }
239
     }
240
    if(this.searchUtils.keyword.length > 0 ){
241
      filtered = true;
242
    }
243
    return filtered;
244
  }
245
  private clearKeywords(){
246
    if(this.searchUtils.keyword.length > 0 ){
247
      this.searchUtils.keyword ='';
248
    }
249
    this.goTo(1);
250
  }
251
  private clearFilters(){
252
    for (var i =0 ; i <  this.filters.length; i++) {
253
         for (var j=0; j <  this.filters[i].values.length; j++) {
254
          if(this.filters[i].values[j].selected) {
255
            this.filters[i].values[j].selected = false;
256
          }
257
         }
258
        this.filters[i].countSelectedValues = 0;
259
    }
260
    this.clearKeywords();
261
  }
262

    
263
  private removeFilter(value:Value,filter:Filter){
264
    filter.countSelectedValues--;
265
    if(value.selected == true){
266
      value.selected = false;
267
     }
268
    this.goTo(1);
269
  }
270
  goTo(page:number = 1){
271

    
272
    this.searchUtils.page=page;
273
   var table = $('#dpTable').DataTable();
274

    
275
   table.page( page - 1  ).draw( false );
276

    
277
   // Object { page: 0, pages: 3, start: 0, end: 10, length: 10, recordsTotal: 28, recordsDisplay: 21, serverSide: false }
278
   var info = table.page.info();
279
   this.searchUtils.totalResults = info.recordsDisplay;
280

    
281
    var urlParameters = this.createUrlParameters(this.filters,true);
282
    this.location.go(location.pathname,urlParameters);
283

    
284
  }
285

    
286
  filterChanged($event){
287
       this.goTo(1);
288
  }
289
  keywordChanged($event) {
290
       this.searchUtils.keyword = $event.value;
291
       this.goTo(1);
292
  }
293
/*
294
	downloadClicked($event) {
295
		if($event.value == true) {
296
		    var queryParameters = this.createSearchQueryParameters(this.filters);
297

    
298
		    this.downloadClick.emit({
299
		        value: queryParameters
300
		    });
301
		}
302
	}
303
*/
304

    
305

    
306
  getSelectedValues(filter):any{
307
    var selected = [];
308
    if(filter.countSelectedValues >0){
309
      for (var i=0; i < filter.values.length; i++){
310
        if(filter.values[i].selected){
311
          selected.push(filter.values[i]);
312
        }
313
      }
314
    }
315
    return selected;
316

    
317
  }
318
  /*
319
  Trigger a table draw in order to get the initial filtering
320
  */
321
  triggerInitialLoad(){
322
      setTimeout(function(){
323
        var table = $('#dpTable').DataTable();
324
        table.page( 0  ).draw( false );
325

    
326
      }, 500);
327
  }
328

    
329
/*
330
Transform initial - not filtered results to get the filtered number
331
*/
332
    transform(results): any {
333
      if(results.length > 0) {
334
        var errorCodes:ErrorCodes = new ErrorCodes();
335
        this.searchUtils.status = errorCodes.LOADING;
336

    
337
        var result = results.filter(row=>this.filterAll(row, this.searchUtils.keyword.toLowerCase(),this.filters));
338

    
339
        let oldTotal = this.searchUtils.totalResults;
340
        this.searchUtils.totalResults = result.length;
341

    
342
        var errorCodes:ErrorCodes = new ErrorCodes();
343
        this.searchUtils.status = errorCodes.DONE;
344
        if(this.searchUtils.totalResults == 0 ){
345
          this.searchUtils.status = errorCodes.NONE;
346
        }
347

    
348
        // if(oldTotal != this.searchUtils.totalResults) {
349
        //   args[3].detectChanges();
350
        // }
351
         return result;
352
      }
353
       return [];
354
    }
355

    
356
    filterAll(row: any, query: string, filters:Filter[]) {
357
      let returnValue: boolean = false;
358

    
359
      if(query) {
360
        if(row.title && row.title.name.toLowerCase().indexOf(query) > -1) {
361
          returnValue = true;
362
        }
363

    
364
        if(row.type && row.type.toLowerCase().indexOf(query) > -1) {
365
          returnValue = true;
366
        }
367

    
368
        if(row.countries && row.countries.length > 0) {
369
          for(let country of row.countries) {
370
            if(country.toLowerCase().indexOf(query) > -1) {
371
              returnValue = true;
372
              break;
373
            }
374
          }
375
        }
376

    
377
        if(row.compatibility && row.compatibility.toLowerCase().indexOf(query) > -1) {
378
          returnValue = true;
379
        }
380

    
381
        if(row.organizations && row.organizations.length > 0) {
382
          for(let organization of row.organizations) {
383
            if(organization.name.toLowerCase().indexOf(query) > -1) {
384
              returnValue = true;
385
              break;
386
            }
387
          }
388
        }
389

    
390
        if(row.name && row.name.toLowerCase().indexOf(query) > -1) {
391
          returnValue = true;
392
        }
393

    
394
        if(row.acronym && row.acronym.toLowerCase().indexOf(query) > -1) {
395
          returnValue = true;
396
        }
397

    
398
        if(row.grantId && row.grantId.toLowerCase().indexOf(query) > -1) {
399
          returnValue = true;
400
        }
401

    
402
        if(row.funder && row.funder.toLowerCase().indexOf(query) > -1) {
403
          returnValue = true;
404
        }
405

    
406
        if(!returnValue) {
407
          return false;
408
        }
409
      }
410

    
411
      for (let filter of filters){
412
        if(filter.countSelectedValues > 0){
413
          for (let value of filter.values){
414
            if(value.selected == true){
415

    
416
              // make it generic in future commit
417
              let field:string = "";
418
              /*
419
              let index: number = -1;
420
              for(let i=0; i<this.columnNames.length; i++) {
421
                if(filter.title == this.columnNames[i]) {
422
                  index = i;
423
                }
424
              }
425
              */
426
              if(filter.title == "Type") {
427
                field = "type";
428
              } else if(filter.title == "Compatibility Level") {
429
                field = "compatibility";
430
              } else if(filter.title == "Funder") {
431
                field = "funder";
432
              }
433

    
434
              if(row[field] == value.name) {
435
                returnValue = true;
436
                if(filter.filterOperator == "or") {
437
                  break;
438
                }
439
              } else {
440
                  if(filter.filterOperator == "and") {
441
                    return false;
442
                  }
443
                  returnValue = false;
444
              }
445
            }
446
          }
447
          if(!returnValue) {
448
            return false;
449
          }
450
        }
451
      }
452

    
453
      return true;
454
    }
455
    filterQuery(data, query){
456
      if(data.toLowerCase().indexOf(query.toLowerCase()) > -1){
457
        return true;
458
      }else{
459
        return false;
460
      }
461
    }
462
    filterData(row: any, query: string, filters:Filter[]) {
463

    
464

    
465
      let returnValue: boolean = false;
466

    
467
      if(query) {
468
        for(var i=0; i <this.columnNames.length; i++){
469
          var r= this.filterQuery(row[i], query);
470
          // console.log(query+" "+ row+" "+r);
471
          if(r) {
472
            returnValue = true;
473
            break;
474
          }
475
        }
476

    
477
        if(!returnValue) {
478
          return false;
479
        }
480
      }
481

    
482
      for (let filter of filters){
483
        if(filter.countSelectedValues > 0){
484
          for (let value of filter.values){
485
            if(value.selected == true){
486
              let field = 1;
487
              /*if(filter.title == "Type") {
488
                field = 1;
489
              } else if(filter.title == "Compatibility Level") {
490
                field = 4;
491
              } else if(filter.title == "Funder") {
492
                field = 3
493
              }*/
494
              for(let i=0; i<this.columnNames.length; i++) {
495
                if(filter.title == this.columnNames[i]) {
496
                  field = i;
497
                }
498
              }
499

    
500
              if(row[field].trim() == value.name.trim()) {
501
                returnValue = true;
502
                if(filter.filterOperator == "or") {
503
                  break;
504
                }
505
              } else {
506
                  if(filter.filterOperator == "and") {
507
                    return false;
508
                  }
509
                  returnValue = false;
510
              }
511
            }
512
          }
513
          if(!returnValue) {
514
            return false;
515
          }
516
        }
517
      }
518

    
519
      return true;
520
    }
521

    
522
    public encode(param: string): string {
523
      return StringUtils.URIEncode(param);
524
    }
525
}
(26-26/36)