Project

General

Profile

1
import {Component, EventEmitter, Input, OnChanges, Output, SimpleChanges, ViewChild} from '@angular/core';
2
import {ActivatedRoute} from '@angular/router';
3
import {AdvancedField, Filter} from './searchUtils/searchHelperClasses.class';
4
import {SearchResearchResultsService} from '../services/searchResearchResults.service';
5
import {ErrorCodes} from '../utils/properties/errorCodes';
6
import {ErrorMessagesComponent} from '../utils/errorMessages.component';
7
import {SearchFields} from '../utils/properties/searchFields';
8
import {SearchCustomFilter, SearchUtilsClass} from './searchUtils/searchUtils.class';
9
import {EnvProperties} from '../utils/properties/env-properties';
10
import {NewSearchPageComponent} from "./searchUtils/newSearchPage.component";
11
import {RangeFilter} from "../utils/rangeFilter/rangeFilterHelperClasses.class";
12

    
13

    
14
@Component({
15
  selector: 'search-research-results',
16
  template: `    
17
    <new-search-page
18
      pageTitle="{{(simpleView?'':'Advanced ')}} Search for {{ getEntityName(resultType, true, true) | titlecase }}"
19
      [entityType]="resultType"
20
      [type]="getEntityName(resultType, true, true)"
21
      [results]="results"
22
      [searchUtils]="searchUtils"
23
      [fieldIds]="fieldIds" [fieldIdsMap]="fieldIdsMap" [selectedFields]="selectedFields"
24
      [csvParams]="csvParams" [csvPath]="getEntityName(resultType, true, false)"
25
      [simpleSearchLink]="simpleSearchLink" [advancedSearchLink]="advancedSearchLink"
26
      [disableForms]="disableForms"
27
      [loadPaging]="loadPaging"
28
      [oldTotalResults]="oldTotalResults"
29
      [openaireLink]=openaireLink
30
      [piwikSiteId]=piwikSiteId [hasPrefix]="hasPrefix"
31
      searchFormClass="publicationsSearchForm"
32
      [sort]=sort
33
      [filters]="filters" [quickFilter]="quickFilter"
34
      [rangeFilters]="rangeFilters" [rangeFields]="rangeFields"
35
      [simpleView]="simpleView" formPlaceholderText="Search by title, author, abstract, DOI, orcid..."
36
      [includeOnlyResultsAndFilter]="includeOnlyResultsAndFilter" [showBreadcrumb]="showBreadcrumb" [showAdvancedSearchLink]="showAdvancedSearchLink"
37
    >
38
    </new-search-page>
39

    
40
  `
41
})
42

    
43
export class SearchResearchResultsComponent {
44
  @Input() resultType: string = "result";
45

    
46
  @Input() simpleSearchLink: string = "";
47
  advancedSearchLink: string = "";
48

    
49
  private errorCodes: ErrorCodes;
50
  private errorMessages: ErrorMessagesComponent;
51
  @Input() piwikSiteId = null;
52
  @Input() hasPrefix: boolean = true;
53
  public results = [];
54
  public filters = [];
55
  public rangeFilters: RangeFilter[] = [];
56

    
57
  public searchUtils: SearchUtilsClass = new SearchUtilsClass();
58
  public searchFields: SearchFields = new SearchFields();
59

    
60
  public fieldIds: string[] = this.searchFields.RESULT_ADVANCED_FIELDS;
61
  public fieldIdsMap = this.searchFields.RESULT_FIELDS;
62
  public rangeFields:string[][] = this.searchFields.RESULT_RANGE_FIELDS;
63
  public selectedFields: AdvancedField[] = [];
64
  public resourcesQuery = "((oaftype exact result) and (resulttypeid exact " + this.resultType + "))";
65
  public csvParams: string;
66
  public disableForms: boolean = false;
67
  public loadPaging: boolean = true;
68
  public oldTotalResults: number = 0;
69
  @Input() openaireLink: string;
70
  @Input() customFilter: SearchCustomFilter = null;
71
  public pagingLimit: number = 0;
72
  public isPiwikEnabled;
73
  public sort: boolean = true;
74
  properties: EnvProperties;
75
  public refineFields: string[] = this.searchFields.RESULT_REFINE_FIELDS;
76
  @ViewChild(NewSearchPageComponent) searchPage: NewSearchPageComponent;
77
  @Input() simpleView: boolean = true;
78
  quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string } = {
79
    filter: null,
80
    selected: true,
81
    filterId: "resultbestaccessright",
82
    value: "Open Access"
83
  };
84
  @Input() includeOnlyResultsAndFilter: boolean = false;
85
  @Input() showBreadcrumb:boolean = false;
86
  @Output() searchPageUpdates = new EventEmitter();
87
  @Input() showAdvancedSearchLink:boolean = true;
88
  subs: any[]=[];
89
  constructor(private route: ActivatedRoute, private _searchResearchResultsService: SearchResearchResultsService) {
90
    this.results = [];
91
    this.errorCodes = new ErrorCodes();
92
    this.errorMessages = new ErrorMessagesComponent();
93
    this.searchUtils.status = this.errorCodes.LOADING;
94
  }
95

    
96
  ngOnInit() {
97
    //TODO add checks about which result types are enabled!
98
    this.subs.push(this.route.data.subscribe((data: { envSpecific: EnvProperties }) => {
99
      this.properties = data.envSpecific;
100
      this.pagingLimit = data.envSpecific.pagingLimit;
101
      this.isPiwikEnabled = data.envSpecific.enablePiwikTrack;
102

    
103
      if (!this.simpleSearchLink) {
104
        this.simpleSearchLink = this.properties.searchLinkToResults;
105
      }
106
      this.advancedSearchLink = this.properties.searchLinkToAdvancedResults;
107
      this.searchUtils.baseUrl = (this.simpleView) ? this.simpleSearchLink : this.advancedSearchLink;
108

    
109
    }));
110

    
111
    this.searchUtils.status = this.errorCodes.LOADING;
112
    var firstLoad = true;
113
    this.subs.push(this.route.queryParams.subscribe(params => {
114
      this.loadPaging = true;
115
      if (params['page'] && this.searchUtils.page != params['page']) {
116
        this.loadPaging = false;
117
        this.oldTotalResults = this.searchUtils.totalResults;
118
      }
119
      var refine = true;
120
      if (this.searchUtils.page != ((params['page'] === undefined) ? 1 : +params['page']) && this.filters && !firstLoad) {
121
        refine = false;
122

    
123
      }
124
      let page = (params['page'] === undefined) ? 1 : +params['page'];
125
      this.searchUtils.page = (page <= 0) ? 1 : page;
126

    
127
      this.searchUtils.size = (params['size'] === undefined) ? 10 : +params['size'];
128
      if (this.searchUtils.size != 5 && this.searchUtils.size != 10 && this.searchUtils.size != 20 && this.searchUtils.size != 50) {
129
        this.searchUtils.size = 10;
130
      }
131
      this.searchUtils.sortBy = (params['sortBy']) ? params['sortBy'] : '';
132
      if (this.searchUtils.sortBy && this.searchUtils.sortBy != "resultdateofacceptance,descending" && this.searchUtils.sortBy != "resultdateofacceptance,ascending") {
133
        this.searchUtils.sortBy = "";
134
      }
135
      this.selectedFields = [];
136
      this.searchPage.prepareSearchPage(this.fieldIds, this.selectedFields, this.refineFields, this.rangeFields, this.fieldIdsMap,this.customFilter,params, this.resultType, this.quickFilter);
137
      this._getResults(this.searchPage.getSearchAPIQueryForAdvancedSearhFields(), this.searchUtils.page, this.searchUtils.size, this.searchUtils.sortBy, refine, this.searchPage.getSearchAPIQueryForRangeFields(params)+this.searchPage.getSearchAPIQueryForRefineFields(params, firstLoad));
138
      firstLoad = false;
139
    }));
140
  }
141

    
142
  ngOnDestroy() {
143
    for(let sub of this.subs){
144
      sub.unsubscribe();
145
    }
146
  }
147

    
148
  public _getResults(parameters: string, page: number, size: number, sortBy: string, refine: boolean, refineFieldsFilterQuery = null) {
149
    if (page > this.pagingLimit) {
150
      size = 0;
151
    }
152
    if (page <= this.pagingLimit || this.searchUtils.status == this.errorCodes.LOADING) {
153
      // if (parameters != null && parameters != '') {
154
      //   this.csvParams = "&fq=(" + this.resourcesQuery + " and (" + parameters + "))";
155
      // } else {
156
      //   this.csvParams = "&fq=" + this.resourcesQuery;
157
      // }
158
      this.csvParams = (parameters ? ("&fq=("+parameters) : "") + (parameters ? ")" : "");
159
      this.csvParams += (refineFieldsFilterQuery ? refineFieldsFilterQuery : "");
160

    
161
      this.searchUtils.status = this.errorCodes.LOADING;
162
      this.disableForms = true;
163
      this.searchPageUpdates.emit({disableForms: this.disableForms,searchUtils: this.searchUtils});
164
      this.results = [];
165
      this.searchUtils.totalResults = 0;
166
      this.subs.push(this._searchResearchResultsService.advancedSearchResults(this.resultType, parameters, page, size, sortBy, this.properties, (refine) ? this.searchPage.getRefineFieldsQuery() : null, this.searchPage.getFields(), refineFieldsFilterQuery)
167
        .subscribe(
168
        data => {
169
          this.searchUtils.totalResults = data[0];
170
          this.results = data[1];
171
          if (refine) {
172
            this.filters = this.searchPage.prepareFiltersToShow(data[2],this.searchUtils.totalResults);
173
            this.rangeFilters = this.searchPage.prepareRangeFiltersToShow();
174
          } else {
175
            this.searchPage.buildPageURLParameters(this.filters, this.rangeFilters, false);
176
          }
177

    
178
          this.searchUtils.status = this.errorCodes.DONE;
179
          if (this.searchUtils.totalResults == 0) {
180
            this.searchUtils.status = this.errorCodes.NONE;
181
          }
182
          this.disableForms = false;
183
          this.searchPageUpdates.emit({disableForms: this.disableForms, searchUtils: this.searchUtils})
184

    
185
          if (this.searchUtils.status == this.errorCodes.DONE) {
186
            // Page out of limit!!!
187
            let totalPages: any = this.searchUtils.totalResults / (this.searchUtils.size);
188
            if (!(Number.isInteger(totalPages))) {
189
              totalPages = (parseInt(totalPages, 10) + 1);
190
            }
191
            if (totalPages < page) {
192
              this.searchUtils.totalResults = 0;
193
              this.searchUtils.status = this.errorCodes.OUT_OF_BOUND;
194
            }
195
          }
196
        },
197
        err => {
198
          this.handleError("Error getting " + this.getEntityName(this.resultType, true, true), err);
199
          this.searchUtils.status = this.errorMessages.getErrorCode(err.status);
200

    
201
          //TODO check erros (service not available, bad request)
202
          // if( ){
203
          //   this.searchUtils.status = ErrorCodes.ERROR;
204
          // }
205
          //var errorCodes:ErrorCodes = new ErrorCodes();
206
          //this.searchUtils.status = errorCodes.NOT_AVAILABLE;
207
          /*if(err.status == '404') {
208
            this.searchUtils.status = this.errorCodes.NOT_FOUND;
209
          } else if(err.status == '500') {
210
            this.searchUtils.status = this.errorCodes.ERROR;
211
          } else {
212
            this.searchUtils.status = this.errorCodes.NOT_AVAILABLE;
213
          }*/
214

    
215
          //this.searchPage.closeLoading();
216
          this.disableForms = false;
217
          this.searchPageUpdates.emit({disableForms: this.disableForms, searchUtils: this.searchUtils})
218

    
219
        }
220
      ));
221
    }
222
  }
223

    
224
  private handleError(message: string, error) {
225
    console.error(this.getEntityName(this.resultType, true, true) + " advanced Search Page: " + message, error);
226
  }
227

    
228
  public getEntityName(entityType: string, plural: boolean, full: boolean): string {
229
    if (entityType == "publication") {
230
      return "publication" + (plural ? "s" : "");
231
    } else if (entityType == "dataset") {
232
      return (full ? "research data" : ("dataset" + (plural ? "s" : "")));
233
    } else if (entityType == "software") {
234
      return "software";
235
    } else if (entityType == "other") {
236
      return (full ? ("other research product" + (plural ? "s" : "")) : "other");
237
    } else if (entityType == "result") {
238
      return (full ? ("research outcome" + (plural ? "s" : "")) : "result");
239
    }
240
  }
241
}
(7-7/8)