Project

General

Profile

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

    
7
import {Observable}                   from 'rxjs';
8

    
9
import {Filter, Value, AdvancedField} from '../searchUtils/searchHelperClasses.class';
10
import {SearchResult}                 from '../../utils/entities/searchResult';
11
import {SearchFields, FieldDetails}   from '../../utils/properties/searchFields';
12
import {SearchUtilsClass}             from './searchUtils.class';
13
import {ModalLoading}                 from '../../utils/modal/loading.component';
14
import {StringUtils, Dates}           from '../../utils/string-utils.class';
15
import {ErrorCodes}                   from '../../utils/properties/errorCodes';
16
import {RouterHelper}                 from '../../utils/routerHelper.class';
17

    
18
import {PiwikService}                 from '../../utils/piwik/piwik.service';
19
import {EnvProperties}                from '../../utils/properties/env-properties';
20
import { SEOService } from '../../sharedComponents/SEO/SEO.service';
21

    
22
@Component({
23
    selector: 'advanced-search-page',
24
    templateUrl: 'advancedSearchPage.component.html'
25
})
26
export class AdvancedSearchPageComponent {
27
  @Input() piwikSiteId = null;
28
  @Input() pageTitle = "";
29
  @Input() results = [];
30
  @Input() type;
31
  @Input() entityType;
32
  @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass();
33
  @Input() fieldIds:  string[];
34
  @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string  }} ;
35
  @Input() selectedFields:AdvancedField[];
36
  @Input() simpleSearchUrl: string;
37
  @ViewChild (ModalLoading) loading : ModalLoading ;
38
  @Input() csvParams: string;
39
  @Input() csvPath: string;
40
  @Input() simpleSearchLink: string = "";
41
  @Input() disableForms:boolean = false;
42
  @Input() loadPaging: boolean = true;
43
  @Input() oldTotalResults: number = 0;
44
  @Input() openaireLink: string;
45
  @Input() connectCommunityId: string;
46
  @Input() sort: boolean = false;
47
  @Input() searchFormClass: string = "searchForm";
48
  piwiksub: any;
49
  public parameterNames:string[] =[];
50
  public parameterValues:string[] =[];
51

    
52
  public baseURLWithParameters:string = '';
53

    
54
  public csvLimit: number = 0;
55
  public pagingLimit: number = 0;
56
  public resultsPerPage: number = 0;
57
  isPiwikEnabled = false;
58
  properties:EnvProperties;
59
  public routerHelper:RouterHelper = new RouterHelper();
60
  public errorCodes:ErrorCodes = new ErrorCodes();
61

    
62
  url = null;
63
  @Output() queryChange  = new EventEmitter();
64
  constructor (private route: ActivatedRoute,
65
               private location: Location,
66
               private _meta: Meta,
67
               private _title: Title,
68
               private _piwikService:PiwikService,
69
               private router: Router,
70
             private seoService: SEOService) {
71
   }
72

    
73
  ngOnInit() {
74
    this.route.data
75
      .subscribe((data: { envSpecific: EnvProperties }) => {
76
        this.properties = data.envSpecific;
77
        this.pagingLimit = data.envSpecific.pagingLimit;
78
        this.resultsPerPage =data.envSpecific.resultsPerPage;
79
        this.csvLimit = data.envSpecific.csvLimit;
80
        this.isPiwikEnabled = data.envSpecific.enablePiwikTrack;
81
        if(typeof window !== 'undefined') {
82
          this.updateUrl(data.envSpecific.baseLink+location.pathname);
83
          this.url = data.envSpecific.baseLink+location.pathname
84
        }
85
        if(typeof document !== 'undefined' && this.isPiwikEnabled){
86
          this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe();
87
        }
88
      });
89

    
90
    var title = "Advanced search "+this.pageTitle;
91
    var description = "Openaire, search, repositories, open access, type, content provider, funder, project, "+ this.pageTitle;
92

    
93
    this.updateTitle(title);
94
    this.updateDescription(description);
95

    
96
    this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl;
97

    
98
    this.updateBaseUrlWithParameters();
99
    this.seoService.createLinkForCanonicalURL(this.properties.baseLink+this.router.url,false);
100

    
101

    
102
  }
103

    
104
  ngOnDestroy() {
105
    if(this.piwiksub){
106
      this.piwiksub.unsubscribe();
107
    }
108
  }
109
  updateDescription(description:string) {
110
    this._meta.updateTag({content:description},"name='description'");
111
    this._meta.updateTag({content:description},"property='og:description'");
112
  }
113
  updateTitle(title:string) {
114
    var _prefix ="OpenAIRE | ";
115
    var _title = _prefix + ((title.length> 50 ) ?title.substring(0,50):title);
116
    this._title.setTitle(_title);
117
    this._meta.updateTag({content:_title},"property='og:title'");
118
  }
119
  updateUrl(url:string) {
120
    this._meta.updateTag({content:url},"property='og:url'");
121
  }
122

    
123
  public getSelectedFiltersFromUrl(params) {
124
    for(var i=0; i< this.fieldIds.length ; i++){
125

    
126
         var fieldId =  this.fieldIds[i];
127
         var fieldparam =  (this.fieldIdsMap[fieldId])?this.fieldIdsMap[fieldId].param:"";
128
         if(!this.fieldIdsMap[fieldId]){
129

    
130
           console.error("Field: "+fieldId +" not found in fieldIds map");
131
         }
132

    
133
         var operatorId =  this.getOperatorParameter(fieldparam);
134
          if(params[fieldparam] != undefined && params[operatorId] != undefined) {
135
              var values:string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1);
136
             var operators:string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1);
137
              if(values.length == operators.length){
138
               for(var j=0; j< values.length ; j++){
139
                 if(this.fieldIdsMap[fieldId].type == "date"){
140
                   var value:string =StringUtils.unquote(values[j]);
141
                   var validDates:boolean = true;
142
                   var dateField:AdvancedField = new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,value,operators[j]) ;
143
                   if(value.indexOf("range") != -1){
144
                     dateField.dateValue.type="range";
145
                     if(value.length < 26 ){
146
                       validDates =false;
147
                     }else{
148
                       if(!Dates.isValidDate(value.substring(5,15)) || !Dates.isValidDate(value.substring(16,26))){
149
                         validDates =false;
150
                       }else {
151
                        dateField.dateValue.from = Dates.getDateFromString(value.substring(5,15));
152
                        dateField.dateValue.to = Dates.getDateFromString(value.substring(16,26));
153
                      }
154
                    }
155
                    //  "rangeYYYY-MM-DD:YYYY-MM-DD"
156
                   }else{
157
                     dateField.dateValue.setDatesByType(value);
158
                   }
159
                   if(validDates){
160
                     this.selectedFields.push(dateField);
161
                   }
162

    
163
                 }
164
                 else{
165
                     this.selectedFields.push(new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,StringUtils.unquote(values[j]),operators[j]) );
166
                 }
167
               }
168
             }
169
         }
170
   }
171
   if(this.selectedFields.length == 0){
172
     this.selectedFields.push(new AdvancedField(this.fieldIds[0],fieldparam,this.fieldIdsMap[this.fieldIds[0]].name,this.fieldIdsMap[this.fieldIds[0]].type,"","and"));
173
   }
174
  }
175
  private createUrlParameters(includePage:boolean){
176
    var params="";
177
    this.parameterNames.splice(0,this.parameterNames.length);
178
    this.parameterValues.splice(0,this.parameterValues.length);
179
    var fields: { [key:string]:{ values:string[], operators:string[] }}={};
180
     for(var i = 0; i< this.selectedFields.length; i++){
181
       if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value.length > 0  || this.selectedFields[i].type == "date" )){
182
        if(!fields[this.selectedFields[i].id]){
183
          fields[this.selectedFields[i].id] = {values:[], operators:[]};
184
          fields[this.selectedFields[i].id].values =[];
185
          fields[this.selectedFields[i].id].operators =[];
186
        }
187
        if(this.selectedFields[i].type == "date"){
188
           if(this.selectedFields[i].dateValue.type == "range"){
189
              fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode("range"+Dates.getDateToString(this.selectedFields[i].dateValue.from)+":"+Dates.getDateToString(this.selectedFields[i].dateValue.to))));
190
          }else{
191
              fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].dateValue.type)));
192
          }
193
        }else{
194
          fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].value)));
195
        }
196
        fields[this.selectedFields[i].id].operators.push(this.selectedFields[i].operatorId);
197

    
198
      }
199
    }
200
    for(var i = 0; i< this.fieldIds.length; i++){
201
      if(fields[this.fieldIds[i]]){
202

    
203
        params+="&"+this.fieldIdsMap[this.fieldIds[i]].param+"="+fields[this.fieldIds[i]].values.join()+
204
        "&"+ this.fieldIdsMap[this.fieldIds[i]].operator+"="+fields[this.fieldIds[i]].operators.join()
205
        this.parameterNames.push(this.fieldIdsMap[this.fieldIds[i]].param);
206
        this.parameterValues.push(fields[this.fieldIds[i]].values.join());
207
        this.parameterNames.push( this.fieldIdsMap[this.fieldIds[i]].operator);
208
        this.parameterValues.push(fields[this.fieldIds[i]].operators.join());
209
      }
210
    }
211
    if(includePage && this.searchUtils.page != 1){
212
      params += "&page="+this.searchUtils.page;
213
    }
214

    
215
    if(this.searchUtils.size != 10) {
216
      params+=((params.length == 0)?'':'&') + 'size=' + this.searchUtils.size;
217
      this.parameterNames.push("size");
218
      this.parameterValues.push(""+this.searchUtils.size);
219
    }
220

    
221
    if(this.sort && this.searchUtils.sortBy) {
222
      params+=((params.length == 0)?'':'&') + 'sortBy=' + this.searchUtils.sortBy;
223
      this.parameterNames.push("sortBy");
224
      this.parameterValues.push(this.searchUtils.sortBy);
225
    }
226

    
227
     return '?'+params;
228
  }
229
  public createQueryParameters(){
230
    var params="";
231
    var countParams = 0;
232
    for(var i = 0; i< this.selectedFields.length; i++){
233
      if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" ||this.selectedFields[i].type == "date")){
234
        //console.log("createQueryParameters::"+this.selectedFields[i].type);
235
        if(this.selectedFields[i].type == "date"){
236
          if(this.selectedFields[i].dateValue.type != "any"){
237
            params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+ '"' + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.from)) + " "
238
            + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " ";
239
          }
240
        }else{
241
          if(this.selectedFields[i].id == "q"){
242
            var op = "";
243
            // if()
244
            params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " ";
245
          }else if(countParams == 0 && this.selectedFields[i].operatorId == "not"){
246
              params += " "+ this.selectedFields[i].id +  " <> "+'"' + StringUtils.URIEncode(this.selectedFields[i].value) +'"' + " ";
247
          }else{
248
            params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " " ) + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+'"' + encodeURIComponent(this.selectedFields[i].value) +'"' + " ";
249

    
250
          }
251
      }
252
        countParams++;
253
      }
254
    }
255

    
256
    //community
257
    if(this.connectCommunityId ){
258
      params += (countParams == 0 ? "" : " and " ) + "communityId exact "+'"' + this.connectCommunityId +'"' + " ";
259
    }
260
     return params;
261

    
262
  }
263
  clearFilters(){
264
  }
265

    
266
  goTo(page:number = 1){
267
     this.searchUtils.page = page;
268
    var urlParameters = this.createUrlParameters(true);
269
    var queryParameters = this.createQueryParameters();
270
    //this.location.go(location.pathname,urlParameters);
271
    this.router.navigate( [this.searchUtils.baseUrl], { queryParams: this.routerHelper.createQueryParams(this.parameterNames, this.parameterValues) } );
272

    
273
    this.queryChange.emit({
274
        value: queryParameters
275
    });
276
    /* Code For Piwik*/
277
        if (typeof localStorage !== 'undefined') {
278
          //console.log("In PreviousRouteRecorder : "+this.router.url );
279
          localStorage.setItem('previousRoute', this.router.url);
280
        }
281
        if(this.isPiwikEnabled && (typeof document !== 'undefined')){
282
          this.piwiksub = this._piwikService.trackView(this.properties, this.pageTitle, this.piwikSiteId).subscribe();
283
        }
284
        /* End Piwik Code */
285
  }
286

    
287
  queryChanged($event) {
288

    
289
     this.goTo(1);
290
  }
291
  pageChanged($event) {
292
    this.searchUtils.page = +$event.value;
293
    this.goTo(this.searchUtils.page);
294
  }
295
  sizeChanged($event) {
296
       this.searchUtils.size = $event.value;
297
       this.goTo(1);
298
  }
299
  sortByChanged($event) {
300
       this.searchUtils.sortBy = $event.value;
301
       this.goTo(1);
302
  }
303

    
304
  /*
305
  * Update the url with proper parameters. This is used as base url in Paging Component
306
  */
307
  public updateBaseUrlWithParameters(){
308
    this.baseURLWithParameters = this.searchUtils.baseUrl + this.createUrlParameters(false);
309
   }
310
   getOperatorParameter(parameter:string):string{
311
     for (let id of this.fieldIds) {
312
       if(this.fieldIdsMap[id]["param"] == parameter){
313
         return this.fieldIdsMap[id]["operator"];
314
       }
315
     }
316
   }
317
   // for loading
318
   public openLoading(){
319
     this.loading.open();
320
   }
321
   public closeLoading(){
322
       this.loading.close();
323
   }
324
}
(5-5/45)