Project

General

Profile

1
import {Component, Input, ViewChild, Output, EventEmitter} from '@angular/core';
2
import {Observable}       from 'rxjs/Observable';
3
import {Location} from '@angular/common';
4
import {Filter, Value,AdvancedField} from '../searchUtils/searchHelperClasses.class';
5
import {SearchResult}     from '../../utils/entities/searchResult';
6
import {SearchFields} from '../../utils/properties/searchFields';
7
import {SearchUtilsClass} from './searchUtils.class';
8
import {ModalLoading} from '../../utils/modal/loading.component';
9
import {StringUtils, Dates} from '../../utils/string-utils.class';
10
import { Meta} from '../../../angular2-meta';
11

    
12

    
13
@Component({
14
    selector: 'advanced-search-page',
15
    template: `
16

    
17
    <div class="uk-margin-top">
18
        <div class="page-header">
19
            <h1>{{pageTitle}}</h1>
20
        </div>
21
        <div>
22
                  <a  *ngIf = "simpleSearchLink && simpleSearchLink.length > 0" routerLinkActive="router-link-active" [routerLink]=simpleSearchLink  class="uk-float-right" >Simple search <span uk-icon="icon: chevron-right"></span></a>
23
                    <advanced-search-form
24
                     [entityType] = "entityType"
25
                     [(fieldIds)]="fieldIds"
26
                     [(fieldIdsMap)]="fieldIdsMap"
27
                     [(selectedFields)]="selectedFields"
28
                                          (queryChange)="queryChanged($event)">
29
                    </advanced-search-form>
30
                        <search-paging [type]="type" [(searchUtils)] = "searchUtils"  [(results)] = "results" [(baseUrl)] = "searchUtils.baseUrl"  [(parameterNames)] = "parameterNames" [(parameterValues)] = "parameterValues"   ></search-paging>
31
                        <search-download [type]="csvPath" [csvParams]="csvParams" [totalResults]="searchUtils.totalResults" ></search-download>
32

    
33
                    <div>
34
                        <search-result  [results]="results"
35
                                        [status]=searchUtils.status
36
                                        [type]="entityType" [urlParam]="urlParam">
37
                        </search-result>
38
                    </div>
39

    
40
        </div>
41
    </div>
42
    <modal-loading [message]= "'Loading results...'"></modal-loading>
43

    
44
    `
45
})
46
export class AdvancedSearchPageComponent {
47
  @Input() pageTitle = "";
48
  @Input() results = [];
49
  @Input() type;
50
  @Input() entityType;
51
  @Input() searchUtils:SearchUtilsClass = new SearchUtilsClass();
52
  @Input() fieldIds:  string[];
53
  @Input() fieldIdsMap;//:{ [key:string]:{ name:string, operator:string, type:string, indexField:string, equalityOperator:string  }} ;
54
  @Input() selectedFields:AdvancedField[];
55
  @Input() simpleSearchUrl: string;
56
  @ViewChild (ModalLoading) loading : ModalLoading ;
57
  @Input() csvParams: string;
58
  @Input() csvPath: string;
59
  @Input() simpleSearchLink: string = "";
60

    
61

    
62

    
63
  public parameterNames:string[] =[];
64
  public parameterValues:string[] =[];
65

    
66
  public urlParam: string;
67
  public baseURLWithParameters:string = '';
68

    
69
  @Output() queryChange  = new EventEmitter();
70
  constructor (private location: Location, private _meta: Meta) {
71
   }
72

    
73
  ngOnInit() {
74
    this.updateTitle("Advanced search "+this.pageTitle);
75
    this.updateDescription("Openaire, search, repositories, open access, type, data provider, funder, project, "+ this.pageTitle);
76
      this.searchUtils.baseUrl = "/" + this.searchUtils.baseUrl;
77
     this.updateBaseUrlWithParameters();
78
     this.defineUrlParam();
79
  }
80
  updateDescription(description:string){
81
    this._meta.updateMeta("description", description);
82
    this._meta.updateMeta("og:description", description);
83
  }
84
  updateTitle(title:string){
85
    var _suffix ="| OpenAIRE";
86
    var _title = ((title.length> 50 ) ?title.substring(0,50):title) + _suffix;
87
    this._meta.setTitle(_title );
88
    this._meta.updateMeta("og:title",_title);
89
  }
90
  private defineUrlParam() {
91
      if(this.entityType == "publication") {
92
          this.urlParam = "articleId";
93
      } else if(this.entityType == "dataset") {
94
          this.urlParam = "datasetId";
95
      } else if(this.entityType == "project") {
96
          this.urlParam = "projectId";
97
      } else if(this.entityType == "organization") {
98
          this.urlParam = "organizationId";
99
      } else if(this.entityType == "person") {
100
          this.urlParam = "personId";
101
      } else {
102
          this.urlParam = "datasourceId";
103
      }
104
  }
105

    
106
  public getSelectedFiltersFromUrl(params){
107
    for(var i=0; i< this.fieldIds.length ; i++){
108

    
109
         var fieldId =  this.fieldIds[i];
110
         var fieldparam =  (this.fieldIdsMap[fieldId])?this.fieldIdsMap[fieldId].param:"";
111
         if(!this.fieldIdsMap[fieldId]){
112

    
113
           console.error("Field: "+fieldId +" not found in fieldIds map");
114
         }
115

    
116
         var operatorId =  this.getOperatorParameter(fieldparam);
117
          if(params[fieldparam] != undefined && params[operatorId] != undefined) {
118
              var values:string [] = StringUtils.URIDecode(params[fieldparam]).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1);
119
             var operators:string [] = (StringUtils.URIDecode(params[operatorId])).split(/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/,-1);
120
              if(values.length == operators.length){
121
               for(var j=0; j< values.length ; j++){
122
                 if(this.fieldIdsMap[fieldId].type == "date"){
123
                   var value:string =StringUtils.unquote(values[j]);
124
                   var validDates:boolean = true;
125
                   var dateField:AdvancedField = new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,value,operators[j]) ;
126
                   if(value.indexOf("range") != -1){
127
                     dateField.dateValue.type="range";
128
                     if(value.length < 26 ){
129
                       validDates =false;
130
                     }else{
131
                       if(!Dates.isValidDate(value.substring(5,15)) || !Dates.isValidDate(value.substring(16,26))){
132
                         validDates =false;
133
                       }else {
134
                        dateField.dateValue.from = Dates.getDateFromString(value.substring(5,15));
135
                        dateField.dateValue.to = Dates.getDateFromString(value.substring(16,26));
136
                      }
137
                    }
138
                    //  "rangeYYYY-MM-DD:YYYY-MM-DD"
139
                   }else{
140
                     dateField.dateValue.setDatesByType(value);
141
                   }
142
                   if(validDates){
143
                     this.selectedFields.push(dateField);
144
                   }
145

    
146
                 }else{
147
                   this.selectedFields.push(new AdvancedField(fieldId,fieldparam,this.fieldIdsMap[fieldId].name,this.fieldIdsMap[fieldId].type,StringUtils.unquote(values[j]),operators[j]) );
148
                 }
149
               }
150
             }
151
         }
152
   }
153
   if(this.selectedFields.length == 0){
154
     this.selectedFields.push(new AdvancedField(this.fieldIds[0],fieldparam,this.fieldIdsMap[this.fieldIds[0]].name,this.fieldIdsMap[this.fieldIds[0]].type,"","and"));
155
   }
156
  }
157
  private createUrlParameters(includePage:boolean){
158
    var params="";
159
    this.parameterNames.splice(0,this.parameterNames.length);
160
    this.parameterValues.splice(0,this.parameterValues.length);
161
    var fields: { [key:string]:{ values:string[], operators:string[] }}={};
162
     for(var i = 0; i< this.selectedFields.length; i++){
163
       if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value.length > 0  || this.selectedFields[i].type == "date" )){
164
        if(!fields[this.selectedFields[i].id]){
165
          fields[this.selectedFields[i].id] = {values:[], operators:[]};
166
          fields[this.selectedFields[i].id].values =[];
167
          fields[this.selectedFields[i].id].operators =[];
168
        }
169
        if(this.selectedFields[i].type == "date"){
170
           if(this.selectedFields[i].dateValue.type == "range"){
171
              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))));
172
          }else{
173
              fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].dateValue.type)));
174
          }
175
        }else{
176
          fields[this.selectedFields[i].id].values.push(StringUtils.quote(StringUtils.URIEncode(this.selectedFields[i].value)));
177
        }
178
        fields[this.selectedFields[i].id].operators.push(this.selectedFields[i].operatorId);
179

    
180
      }
181
    }
182
    for(var i = 0; i< this.fieldIds.length; i++){
183
      if(fields[this.fieldIds[i]]){
184

    
185
        params+="&"+this.fieldIdsMap[this.fieldIds[i]].param+"="+fields[this.fieldIds[i]].values.join()+
186
        "&"+this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param)+"="+fields[this.fieldIds[i]].operators.join()
187
        this.parameterNames.push(this.fieldIdsMap[this.fieldIds[i]].param);
188
        this.parameterValues.push(fields[this.fieldIds[i]].values.join());
189
        this.parameterNames.push(this.getOperatorParameter(this.fieldIdsMap[this.fieldIds[i]].param));
190
        this.parameterValues.push(fields[this.fieldIds[i]].operators.join());
191
      }
192
    }
193
    if(includePage && this.searchUtils.page != 1){
194
      params += "&page="+this.searchUtils.page;
195
    }
196
     return '?'+params;
197
  }
198
  public createQueryParameters(){
199
    var params="";
200
    var countParams = 0;
201
    for(var i = 0; i< this.selectedFields.length; i++){
202
      if(this.fieldIdsMap[this.selectedFields[i].id] != undefined && (this.selectedFields[i].value != "" ||this.selectedFields[i].type == "date")){
203
        console.log("createQueryParameters::"+this.selectedFields[i].type);
204
        if(this.selectedFields[i].type == "date"){
205
          if(this.selectedFields[i].dateValue.type != "any"){
206
            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)) + " "
207
            + StringUtils.URIEncode(Dates.getDateToString(this.selectedFields[i].dateValue.to)) + '"' + " ";
208
          }
209
        }else{
210
          if(this.selectedFields[i].id == "q"){
211
            var op = "";
212
            // if()
213
            params += (countParams == 0 ? "" : this.selectedFields[i].operatorId) + " " + '"' + StringUtils.URIEncode(this.selectedFields[i].value) + '"' + " ";
214
          }else if(countParams == 0 && this.selectedFields[i].operatorId == "not"){
215
              params += " "+ this.selectedFields[i].id +  " <> "+'"' + StringUtils.URIEncode(this.selectedFields[i].value) +'"' + " ";
216
          }else{
217
            params += (countParams == 0 ? "" : this.selectedFields[i].operatorId + " " ) + this.selectedFields[i].id + this.fieldIdsMap[this.selectedFields[i].id].equalityOperator+'"' + encodeURIComponent(this.selectedFields[i].value) +'"' + " ";
218

    
219
          }
220
      }
221
        countParams++;
222
      }
223
    }
224

    
225
     return params;
226

    
227
  }
228
  clearFilters(){
229
  }
230

    
231
  goTo(page:number = 1){
232
     this.searchUtils.page = page;
233
    var urlParameters = this.createUrlParameters(true);
234
    var queryParameters = this.createQueryParameters();
235
    this.location.go(location.pathname,urlParameters);
236
    this.queryChange.emit({
237
        value: queryParameters
238
    });
239

    
240
  }
241

    
242
  queryChanged($event) {
243

    
244
     this.goTo(1);
245
  }
246
  pageChanged($event) {
247
    this.searchUtils.page = +$event.value;
248
    this.goTo(this.searchUtils.page);
249
  }
250
  /*
251
  * Update the url with proper parameters. This is used as base url in Paging Component
252
  */
253
  public updateBaseUrlWithParameters(){
254
    this.baseURLWithParameters = this.searchUtils.baseUrl + this.createUrlParameters(false);
255
   }
256
   getOperatorParameter(parameter:string):string{
257
     if(parameter.length > 2){
258
       return parameter.substring(0,2);
259
     }else if(parameter == "q"){
260
       return "op";
261
     }else{
262
       return parameter+"Op";
263
     }
264
   }
265
   // for loading
266
   public openLoading(){
267
     this.loading.open();
268
   }
269
   public closeLoading(){
270
       this.loading.close();
271
   }
272
}
(3-3/24)