import {Component, Input, ViewChild} from '@angular/core'; import {SearchCrossrefService} from '../../claim-utils/service/searchCrossref.service'; import {SearchDataciteService} from '../../claim-utils/service/searchDatacite.service'; import {ModalLoading} from '../../../utils/modal/loading.component'; import {Dates, DOI, Identifier} from '../../../utils/string-utils.class'; import {EnvProperties} from '../../../utils/properties/env-properties'; import {ClaimEntity} from "../../claim-utils/claimHelper.class"; import {Subscriber} from "rxjs"; declare var UIkit: any; @Component({ selector: 'bulk-claim', template: `
Upload a DOI's CSV file  
Uploaded file contains {{allIds.length}} {{((allIds.length == 1) ? 'DOI' : 'DOIs')}}.
Basket exceeds the size limit.
Only No results added.
{{foundIds.length}} {{((foundIds.length == 1) ? 'result was' : 'results were')}} succefully fetched from CrossRef{{ ' and ' }}Datacite.
{{duplicateIds.length | number}} duplicate DOIs in {{((duplicateIds.length == 1) ? 'line' : 'lines')}} {{duplicateIdsRow}}.
Couldn't be fetched:
  • "{{id}}" in line {{notFoundIdsRow[i]}}
No valid DOIs:
  • "{{id}}" in line {{noValidIdsRow[i]}}
Please make sure that the uploaded file, is a csv file with the proper format.
` }) export class BulkClaimComponent { filesToUpload: Array; source: string = "crossref"; type: string = "publication"; @Input() public select: boolean = true; @Input() public results; @Input() public properties: EnvProperties; allIds: string[] = []; foundIds: string[] = []; existedIds: string[] = []; duplicateIds: string[] = []; duplicateIdsRow: number[] = []; notFoundIds: string[] = []; notFoundIdsRow: number[] = []; noValidIds: string[] = []; noValidIdsRow: number[] = []; showReport: boolean = false; @ViewChild(ModalLoading) loading: ModalLoading; errorMessage = ""; enableUpload: boolean = true; @Input() localStoragePrefix: string = ""; exceedsLimit = false; @Input() basketLimit ; tooltip = `
Up to 100 DOIs
CSV format:
"DOI","ACCESS_MODE","DATE"

- DOI is required
- Access mode:
OPEN, CLOSED, EMBARGO
- Embargo end date:
YYYY-MM-DD
`; constructor(private _searchCrossrefService: SearchCrossrefService, private _searchDataciteService: SearchDataciteService) { this.filesToUpload = []; } ngOnInit() { } subscriptions = []; ngOnDestroy() { this.subscriptions.forEach(subscription => { if (subscription instanceof Subscriber) { subscription.unsubscribe(); } }); } upload() { this.enableUpload = false; this.showReport = false; this.errorMessage = ""; console.log(this.filesToUpload); if (this.filesToUpload.length == 0) { this.errorMessage = "There is no selected file to upload."; return; } else { if (this.filesToUpload[0].name.indexOf(".csv") == -1 || (this.filesToUpload[0].type != "text/csv" && this.filesToUpload[0].type != "application/vnd.ms-excel")) { this.errorMessage = "No valid file type. The required type is CSV"; return; } } this.loading.open(); this.makeFileRequest(this.properties.utilsService + '/upload', [], this.filesToUpload).then((result) => { const rows = (result as any).split('\n'); // I have used space, you can use any thing. this.exceedsLimit = false; let invalid_rows = 0; this.duplicateIds = []; this.existedIds = []; this.allIds = []; this.foundIds = []; this.noValidIds = []; this.results.slice(0, this.results.length); this.notFoundIds = []; let currentLength = this.results.length; for (let i = 0; i < ( rows.length); i++) { if (rows[i] && rows[i] != null && rows[i]!="") { const values = rows[i].split(','); let id = BulkClaimComponent.removeDoubleQuotes(values[0]); if (DOI.isValidDOI(id)) { id = Identifier.getRawDOIValue(id); let accessMode = (values[1] != undefined) ? BulkClaimComponent.removeDoubleQuotes(values[1]) : "OPEN"; accessMode = (BulkClaimComponent.validateAccessMode(accessMode) ? accessMode : "OPEN"); let embargoDate = (values[2] != undefined) ? Dates.getDateFromString(BulkClaimComponent.removeDoubleQuotes(values[2])) : Dates.getDateToday(); if (this.allIds.indexOf(id) > -1) { this.duplicateIds.push(id); this.duplicateIdsRow.push(i + 1); } else { this.allIds.push(id); if (currentLength < this.basketLimit){ currentLength++; this.fetchResult(id, accessMode, Dates.getDateToString(embargoDate), i + 1); }else{ this.exceedsLimit = true; } } } else { this.noValidIds.push(id); this.noValidIdsRow.push(i + 1); } } else { invalid_rows++; } } if (rows.length == 0 || rows.length == invalid_rows || rows.length == (invalid_rows + this.noValidIds.length) || this.basketLimit <= this.results.length) { this.endOfFetching(); } }, (error) => { this.enableUpload = true; this.loading.close(); this.errorMessage = "An error occured."; BulkClaimComponent.handleError("Error uploading file", error); }); } private static removeDoubleQuotes(value) { if (value.indexOf('"') == 0) { value = value.substring(1, value.length); } const index = +value.indexOf('"'); if (index == (value.length - 1) || index == (value.length - 2)) { value = value.substring(0, index); } return value; } private static validateAccessMode(value) { const accessModes = ["OPEN", "CLOSED", "EMBARGO"]; return accessModes.indexOf(value) > -1; } fileChangeEvent(fileInput: any) { this.filesToUpload = >fileInput.target.files; this.upload(); } makeFileRequest(url: string, params: Array, files: Array) { return new Promise((resolve, reject) => { const formData: any = new FormData(); const xhr = new XMLHttpRequest(); for (let i = 0; i < files.length; i++) { formData.append("uploads[]", files[i], files[i].name); } xhr.onreadystatechange = function () { if (xhr.readyState == 4) { if (xhr.status == 200) { resolve(xhr.response); } else { reject(xhr.response); } } } xhr.open("POST", url, true); xhr.send(formData); }); } fetchResult(id: string, accessMode: string, date: string, row: number) { // this.subscriptions.push(this._searchCrossrefService.searchCrossrefByDOIs([id], this.properties, true, true).subscribe( this.subscriptions.push(this._searchCrossrefService.searchCrossrefByDOI(id).subscribe( data => { if (data.length > 0) { const result:ClaimEntity = data[0]; this.foundIds.push(id); result.result.accessRights = accessMode; result.result.embargoEndDate = date; if(!this.isSelected(result)){ this.results.push(result); }else{ this.existedIds.push(id); } this.endOfFetching(); } else { this.searchInDatacite(id, accessMode, date, row); // this.notFoundIds.push(id); } }, err => { //console.log(err); BulkClaimComponent.handleError("Error getting crossref by DOIs: " + id, err); this.notFoundIds.push(id); this.notFoundIdsRow.push(row); this.endOfFetching(); } )); } searchInDatacite(id: string, accessMode: string, date: string, row: number) { this.subscriptions.push(this._searchDataciteService.getDataciteResultByDOI(id, this.properties, true).subscribe( result => { if (result) { this.foundIds.push(id); result.result.accessRights = accessMode; result.result.embargoEndDate = date; if(!this.isSelected(result)){ this.results.push(result); }else{ this.existedIds.push(id); } } else { this.notFoundIds.push(id); this.notFoundIdsRow.push(row); } this.endOfFetching(); }, err => { //console.log(err); BulkClaimComponent.handleError("Error getting datacite resultentityI: " + id, err); this.notFoundIds.push(id); this.notFoundIdsRow.push(row); this.endOfFetching(); } )); } endOfFetching() { // if (this.basketLimit <= this.results.length) { // this.enableUpload = true; // this.loading.close(); // return; // } // console.log(this.allIds.length+" "+this.foundIds.length +" "+ this.notFoundIds.length+" "+this.existedIds.length + " " + this.results.length); if (this.allIds.length == this.foundIds.length + this.notFoundIds.length || this.basketLimit <= (this.results.length+this.existedIds.length+this.notFoundIds.length)) { this.showReport = true; this.enableUpload = true; this.loading.close(); if (this.results != null) { localStorage.setItem(this.localStoragePrefix, JSON.stringify(this.results)); } } } private static handleError(message: string, error) { console.error("Bulk Claim (component): " + message, error); } private isSelected(result: ClaimEntity) { let found: boolean = false; const id = result.id; for (let _i = 0; _i < this.results.length; _i++) { let item = this.results[_i]; if (item.id && item.id == id) { found = true; break; } } return found; // indexOf doesn't work when results came from // return this.selectedResults.indexOf(entity)!=-1; } }