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
          console.log("Rows:" + rows.length);
114
          this.exceedsLimit = false;
115
          var i = 0;
116
          var invalid_rows = 0;
117
          this.duplicateIds = [];
118
          this.allIds = [];
119
          this.foundIds = [];
120
          this.noValidIds = [];
121
          this.results.slice(0,this.results.length);
122
          this.notFoundIds = [];
123

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

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

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

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

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

    
188
      return false;
189
  }
190

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

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

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

    
221
            var result = data[0];
222
            if(data.length > 0){
223
              this.foundIds.push(id);
224
              result.embargoEndDate = date;
225
              this.results.push(result);
226
              this.endOfFetching();
227
            }else{
228
              this.searchInDatacite(id,accessMode,date, row);
229
              // this.notFoundIds.push(id);
230
            }
231
           },
232
          err => {
233
            console.log(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.notFoundIds.push(id);
259
            this.notFoundIdsRow.push(row);
260
            this.endOfFetching();
261
          }
262
        );
263
  }
264
  endOfFetching(){
265
    if(this.limit == this.results.length){
266
      this.enableUpload = true;
267
      this.loading.close();
268
      return;
269
    }
270
    if(this.allIds.length == this.foundIds.length+this.notFoundIds.length ){
271
      this.showReport = true;
272
      this.enableUpload = true;
273
      this.loading.close();
274
      if(this.results != null){
275
            localStorage.setItem(this.localStoragePrefix + "results", JSON.stringify(this.results));
276
          }
277
    }
278

    
279
  }
280
}
(1-1/2)