Project

General

Profile

1
import {Component, Input, Output, EventEmitter,ViewChild} from '@angular/core';
2
import {Observable}       from 'rxjs/Observable';
3
import {SearchCrossrefService} from '../../claim-utils/service/searchCrossref.service';
4
import {SearchDataciteService} from '../../claim-utils/service/searchDatacite.service';
5

    
6
import {ModalLoading} from '../../../utils/modal/loading.component';
7
import {Dates, DOI} from '../../../utils/string-utils.class';
8
import {ClaimResult} from '../../claim-utils/claimEntities.class';
9
import{EnvProperties} from '../../../utils/properties/env-properties';
10
declare var UIkit:any;
11

    
12

    
13
@Component({
14
    selector: 'bulk-claim',
15
    template: `
16
    <div class="uk-animation  " style=" ">
17
      <form class=" uk-padding uk-padding-medium uk-padding-remove-left uk-margin-left uk-margin-small-top ">
18

    
19
      <div class="uk-grid">
20
        <div class="uk-width-expand">
21
          <div class="uk-text-lead">Upload a DOI csv file <helper  div="link-result-bulk" tooltip=true ></helper></div>
22
          <!--h3 for="exampleInputFile">Or upload a DOI csv file:</h3-->
23
          <label for="exampleInputFile">Select a file: </label>
24
          <div class="js-upload" uk-form-custom>
25
            <input id="exampleInputFile" class="uk-width-medium" type="file"  (change)="fileChangeEvent($event)"/>
26
            <button class="uk-button  portal-button" type="button" tabindex="-1" [class.disabled]="!enableUpload" ><span class="uk-margin-small-right uk-icon"  >
27
            <svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <polyline fill="none" stroke="#000" points="5 8 9.5 3.5 14 8 "></polyline> <rect x="3" y="17" width="13" height="1"></rect>
28
             <line fill="none" stroke="#000" x1="9.5" y1="15" x2="9.5" y2="4"></line></svg></span> Select</button>
29
            <!--button class="uk-button uk-button-small" [class.disabled]="!enableUpload" type="button" (click)="upload()">Upload</button-->
30
        </div>
31
          <div *ngIf="showReport"  uk-alert  class="uk-alert uk-alert-primary" role="alert" >
32
            <a class="uk-alert-close" uk-close></a>
33
            <div>Uploaded file contains {{allIds.length}} {{((allIds.length==1)?'DOI':'DOIs')}}.
34
              <span *ngIf="allIds.length > 0">{{foundIds.length}} {{((foundIds.length==1)?'result was':'results were')}} succefully  fetched from CrossRef and Datacite.</span>
35
            </div>
36
            <div *ngIf ="duplicateIds.length > 0"  >{{duplicateIds.length | number}} duplicate DOIs in {{((duplicateIds.length==1)?'line':'lines')}} {{duplicateIdsRow}}.</div>
37
            <div *ngIf = "notFoundIds.length > 0"   >Couldn't be found:
38
              <ul class="">
39
                <li *ngFor="let id of notFoundIds; let i = index">"{{id}}" in line {{notFoundIdsRow[i]}}</li>
40
               </ul>
41
            </div>
42
            <div *ngIf = "noValidIds.length > 0"   >No valid DOIs:
43
              <ul class="">
44
                <li *ngFor="let id of noValidIds; let i = index">"{{id}}" in line {{noValidIdsRow[i]}}</li>
45
               </ul>
46
            </div>
47
            <div *ngIf = "allIds.length == 0 || foundIds.length == 0"   > Please make sure that the uploaded file, is a csv file with the proper format. </div>
48

    
49
          </div>
50
          <div *ngIf="errorMessage.length > 0 " class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div>
51
          <modal-loading [message]= "'Uploading, reading your documet and fetching results. Please give us a moment..'"></modal-loading>
52
        </div>
53
        <!--helper  div="link-result-bulk" ></helper-->
54
      </div>
55
    </form>
56

    
57

    
58

    
59
</div>
60
    `
61

    
62
})
63
//[(ngModel)]="date"
64
export class BulkClaimComponent {
65
  filesToUpload: Array<File>;
66
  navigateTo: string = "Search";
67
  source: string = "crossref";
68
  type : string = "publication";
69
  resultsFromSearch:number;
70
  @Input() public select:boolean = true ;
71
  @Input() public results;
72
  @Input() public properties:EnvProperties;
73

    
74
  allIds:string[] = [];
75
  foundIds:string[] = [];
76
  duplicateIds:string[] = [];
77
  duplicateIdsRow:number[] = [];
78
  notFoundIds:string[] = [];
79
  notFoundIdsRow:number[] = [];
80
  noValidIds:string[] = [];
81
  noValidIdsRow:number[] = [];
82
  showReport:boolean = false;
83
  showInfo :boolean = false;
84
  @ViewChild (ModalLoading) loading : ModalLoading ;
85
  errorMessage = "";
86
  infoMEssage = "";
87
  enableUpload:boolean = true;
88
  @Input() localStoragePrefix:string="";
89
  exceedsLimit = false;
90
  limit =150;
91
  constructor(private _searchCrossrefService: SearchCrossrefService, private _searchDataciteService: SearchDataciteService) {
92
      this.filesToUpload = [];
93
  }
94
  ngOnInit() {}
95

    
96
  upload() {
97
    this.enableUpload = false;
98
    this.showReport = false;
99
    this.errorMessage = "";
100
    if(this.filesToUpload.length == 0){
101
      this.errorMessage = "There is no selected file to upload.";
102
      return ;
103
    }else{
104
       if(this.filesToUpload[0].name.indexOf(".csv") == -1 || this.filesToUpload[0].type != "text/csv"){
105
        this.errorMessage = "No valid file type. The required type is CSV";
106
        return ;
107
      }
108
    }
109
    this.loading.open();
110

    
111
    this.makeFileRequest(this.properties.uploadService, [], this.filesToUpload).then((result) => {
112
          var rows = (result as any).split('\n');  // I have used space, you can use any thing.
113
          this.exceedsLimit = false;
114
          var i = 0;
115
          var invalid_rows = 0;
116
          this.duplicateIds = [];
117
          this.allIds = [];
118
          this.foundIds = [];
119
          this.noValidIds = [];
120
          this.results.slice(0,this.results.length);
121
          this.notFoundIds = [];
122

    
123
          if(rows.length +  this.results.length > this.limit){
124
            this.exceedsLimit = true;
125
              UIkit.notification({
126
                  message : 'Your basket exceeds the number of allowed results (150)',
127
                  status  : 'warning',
128
                  timeout : 1500,
129
                  pos     : 'top-center'
130
              });
131

    
132
          }
133
          for(i=0;i<((rows.length>this.limit-this.results.length)?(this.limit-this.results.length):rows.length);i++){
134
            if(rows[i] && rows[i] != null ){
135
              var values = rows[i].split(',');
136

    
137
              var id=this.removeDoubleQuotes(values[0]);
138
              if(DOI.isValidDOI(id)){
139
                var accessMode = (values[1] != undefined) ? this.removeDoubleQuotes(values[1]):"OPEN";
140
                accessMode = (this.validateAccessMode(accessMode)?accessMode:"OPEN");
141
                var embargoDate =(values[2] != undefined) ? this.removeDoubleQuotes(values[2]):Dates.getDateToday();
142
                embargoDate = (Dates.isValidDate(embargoDate)?embargoDate:Dates.getDateToday());
143
                if(this.allIds.indexOf(id)>-1){
144
                  this.duplicateIds.push(id);
145
                  this.duplicateIdsRow.push(i+1);
146
                }else{
147
                  this.allIds.push(id);
148
                  this.fetchResult(id,accessMode,embargoDate,i+1);
149
                }
150
             }else{
151
               this.noValidIds.push(id);
152
               this.noValidIdsRow.push(i+1);
153
             }
154
           }else{
155
             invalid_rows++;
156
           }
157

    
158
         }
159
         if(rows.length == 0 || rows.length == invalid_rows || rows.length == (invalid_rows + this.noValidIds.length) || this.limit == this.results.length ){
160
           this.endOfFetching();
161
         }
162

    
163
       }, (error) => {
164
         this.enableUpload = true;
165
          console.log(error);
166
          this.loading.close();
167
          //this.errorMessage = "An error occured while uploading...";
168
          this.handleError("Error uploading file", error);
169
      });
170
  }
171
  private removeDoubleQuotes(value){
172
     if(value.indexOf('"')== 0){
173
        value = value.substring(1,value.length);
174
      }
175
      var index =+value.indexOf('"');
176
      if(index == (value.length - 1) || index == (value.length - 2) ){
177
        value = value.substring(0,index);
178
      }
179
      return value;
180
  }
181
  private validateAccessMode(value){
182
    var accessModes = ["OPEN", "CLOSED", "EMBARGO"];
183
     if(accessModes.indexOf(value) > -1){
184
        return true;
185
      }
186

    
187
      return false;
188
  }
189

    
190
  fileChangeEvent(fileInput: any){
191
      this.filesToUpload = <Array<File>> fileInput.target.files;
192
      this.upload();
193
  }
194

    
195
  makeFileRequest(url: string, params: Array<string>, files: Array<File>) {
196
      return new Promise((resolve, reject) => {
197
          var formData: any = new FormData();
198
          var xhr = new XMLHttpRequest();
199
          for(var i = 0; i < files.length; i++) {
200
              formData.append("uploads[]", files[i], files[i].name);
201
          }
202
          xhr.onreadystatechange = function () {
203
              if (xhr.readyState == 4) {
204
                  if (xhr.status == 200) {
205
                      resolve(xhr.response);
206
                  } else {
207
                      reject(xhr.response);
208
                  }
209
              }
210
          }
211
          xhr.open("POST", url, true);
212
          xhr.send(formData);
213
      });
214
  }
215

    
216
  fetchResult(id:string,accessMode:string,date:string, row:number){
217
        this._searchCrossrefService.searchCrossrefByDOIs([id], this.properties.searchCrossrefAPIURL, true).subscribe(
218
          data => {
219

    
220
            var result = data[0];
221
            if(data.length > 0){
222
              this.foundIds.push(id);
223
              result.embargoEndDate = date;
224
              this.results.push(result);
225
              this.endOfFetching();
226
            }else{
227
              this.searchInDatacite(id,accessMode,date, row);
228
              // this.notFoundIds.push(id);
229
            }
230
           },
231
          err => {
232
            //console.log(err);
233
            this.handleError("Error getting crossref by DOIs: "+id, err);
234
            this.notFoundIds.push(id);
235
            this.notFoundIdsRow.push(row);
236
            this.endOfFetching();
237
          }
238
        );
239
  }
240
  searchInDatacite(id:string,accessMode:string,date:string, row:number){
241
        this._searchDataciteService.getDataciteResultByDOI(id,this.properties,true).subscribe(
242
          items => {
243

    
244
            if(items.length > 0){
245
              var result = items[0];
246

    
247
              this.foundIds.push(id);
248
              result.embargoEndDate = date;
249
              this.results.push(result);
250
            }else{
251
              this.notFoundIds.push(id);
252
              this.notFoundIdsRow.push(row);
253
            }
254
            this.endOfFetching();
255
           },
256
          err => {
257
            //console.log(err);
258
            this.handleError("Error getting datacite result by DOI: "+id, err);
259
            this.notFoundIds.push(id);
260
            this.notFoundIdsRow.push(row);
261
            this.endOfFetching();
262
          }
263
        );
264
  }
265
  endOfFetching(){
266
    if(this.limit == this.results.length){
267
      this.enableUpload = true;
268
      this.loading.close();
269
      return;
270
    }
271
    if(this.allIds.length == this.foundIds.length+this.notFoundIds.length ){
272
      this.showReport = true;
273
      this.enableUpload = true;
274
      this.loading.close();
275
      if(this.results != null){
276
            localStorage.setItem(this.localStoragePrefix + "results", JSON.stringify(this.results));
277
          }
278
    }
279

    
280
  }
281

    
282
  private handleError(message: string, error) {
283
      console.error("Bulk Claim (component): "+message, error);
284
  }
285
}
(1-1/2)