[Trunk | Library]: Add /orcid folder with files, for adding-removing works and getting orcid tokens for user.

git-svn-id: https://svn.driver.research-infrastructures.eu/driver/dnet40/modules/uoa-services-library/trunk/ng-openaire-library/src/app@60230 d315682c-612b-4755-9ff5-7f18f6832af3
This commit is contained in:
konstantina.galouni 2021-01-13 18:23:31 +00:00
parent e772594e93
commit 948831e201
5 changed files with 1195 additions and 0 deletions

View File

@ -0,0 +1,506 @@
import {Component, Input, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {Subscriber, Subscription} from "rxjs";
import {OrcidService} from "./orcid.service";
import {ResultLandingInfo} from "../utils/entities/resultLandingInfo";
import {ResultLandingService} from "../landingPages/result/resultLanding.service";
import {properties} from "../../../environments/environment";
declare var UIkit: any;
@Component({
styles: [
'.add-orcid-button { background-color: #a6ce39; color: #fff; border: 1px solid #a6ce39; } ' +
'.add-orcid-button:hover { background-color: #b6d65c; border-color: #b6d65c; } ' +
'.remove-orcid-button { background-color: #fff; color: #ff3d33; border: 1px solid #ff3d33 }' +
'.remove-orcid-button:hover { color: #ff0d00; border-color: #ff0d00; } ' +
' a:not(:hover) .orcid-color { color: #a6ce39; }'
],
selector: 'orcid-work',
template: `
<!-- <div *ngIf="putCodes">YES</div>-->
<!-- <div *ngIf="!putCodes">NO</div>-->
<!-- <a *ngIf="!putCodes || putCodes.length == 0" (click)="openWorkModal('Add work in your ORCID record')">-->
<!-- <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="">{{" "}}-->
<!-- <span>Add to ORCID</span>-->
<!-- </a>-->
<ng-container *ngIf="pageType == 'search'">
<a *ngIf="!putCodes || putCodes.length == 0"
(click)="saveWorkPreparation();" title="Add this work to your ORCID record"
[class]="'uk-margin-right uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')">
<svg *ngIf="!showLoading" width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" data-svg="plus">
<rect x="7" y="1" width="1" height="13" fill="#A6CE39"></rect>
<rect x="1" y="7" width="13" height="1" fill="#A6CE39"></rect>
</svg>
<span *ngIf="showLoading" class="uk-icon icon-button"><loading></loading></span>
<span class="uk-margin-small-left">Add to <span class="orcid-color">ORCID</span></span>
</a>
<!--(click)="openWorkModal('Work is in your ORCID record')"-->
<a *ngIf="putCodes && putCodes.length > 0"
(click)="deleteWorks();" title="Remove this work from your ORCID record"
[class]="'uk-margin-right uk-flex uk-flex-middle '+ (showLoading ? 'uk-disabled' : '')">
<!-- <img src="assets/common-assets/common/ORCIDiD_icon16x16.png" alt="">{{" "}}-->
<svg *ngIf="!showLoading" width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg" data-svg="minus">
<rect height="1" width="13" y="7" x="1" fill="#FF3D33"></rect>
</svg>
<span *ngIf="showLoading" class="uk-icon icon-button"><loading></loading></span>
<span class="uk-margin-small-left">Remove from <span class="orcid-color">ORCID</span></span>
</a>
</ng-container>
<ng-container *ngIf="pageType == 'landing'">
<a *ngIf="!putCodes || putCodes.length == 0"
(click)="saveWorkPreparation();" title="Add this work to your ORCID record"
[class]="'uk-link-text uk-text-bold uk-text-uppercase '+ (showLoading ? 'uk-disabled' : '')">
<span *ngIf="!showLoading" class="uk-icon-button add-orcid-button uk-icon">
<svg width="15" height="15" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" data-svg="plus">
<rect x="7.5" y="1" width="1" height="15" fill="#A6CE39"></rect>
<rect x="1" y="7.5" width="15" height="1" fill="#A6CE39"></rect>
</svg>
</span>
<span *ngIf="showLoading" class="uk-icon icon-button"><loading></loading></span>
<span class="uk-margin-small-left">Add to <span class="orcid-color">ORCID</span></span>
</a>
<a *ngIf="putCodes && putCodes.length > 0"
(click)="deleteWorks();" title="Remove this work from your ORCID record"
[class]="'uk-link-text uk-text-bold uk-text-uppercase '+ (showLoading ? 'uk-disabled' : '')">
<span *ngIf="!showLoading" class="uk-icon-button remove-orcid-button uk-icon">
<svg width="15" height="15" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" data-svg="minus">
<rect height="1" width="15" y="7.5" x="1" fill="#FF3D33"></rect>
</svg>
</span>
<span class="uk-icon icon-button loading-action-button"><loading></loading></span>
<span class="uk-margin-small-left">Remove from <span class="orcid-color">ORCID</span></span>
</a>
</ng-container>
<!--<div *ngIf="showLoading" class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">-->
<!-- <span class="loading-gif uk-align-center"></span>-->
<!--</div>-->
<!--<i class="uk-icon-spinner"></i>-->
<modal-alert #workModal [classTitle]="'landing-modal-header uk-padding-small'"
[classBody]="'landing-modal uk-padding-remove'">
<div class="uk-text-center uk-padding-small">
<div>{{requestGrantMessage}}</div>
<div class="uk-margin-medium-top uk-align-right">
<button (click)="closeWorkModal()" type="submit"
class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">
<span>Cancel</span>
</button>
<button (click)="openGrantWindow()" type="submit"
class="uk-button uk-padding-small uk-padding-remove-vertical uk-margin-left uk-button-primary">
<span>Grant OpenAIRE</span>
</button>
</div>
</div>
</modal-alert>
<!-- <modal-alert #workModal [classTitle]="'landing-modal-header uk-padding-small'"-->
<!-- [classBody]="'landing-modal uk-padding-remove'">-->
<!-- <div class="uk-text-center uk-padding-small">-->
<!-- <div *ngIf="!putCodes || putCodes.length == 0">-->
<!-- <div>-->
<!-- You are about to add this result in your ORCID record.-->
<!-- </div>-->
<!-- <div class="uk-margin-small-top">-->
<!-- <button [disabled]="requestGrant || showLoading"-->
<!-- (click)="saveWorkPreparation();" type="submit"-->
<!-- [class]="'uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary '-->
<!-- + (requestGrant || showLoading ? 'uk-disabled' : '')">-->
<!-- <span>Add work</span>-->
<!-- </button>-->
<!-- <button (click)="closeWorkModal()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- </div>-->
<!-- </div>-->
<!-- -->
<!-- <div *ngIf="putCodes && putCodes.length > 0">-->
<!-- <div>-->
<!-- Last time we checked, this work was in your ORCID record. Refresh to retrieve changes to your work from ORCID.-->
<!-- </div>-->
<!-- <div class="uk-margin-small-top">-->
<!-- <button (click)="getWorks()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Refresh work</span>-->
<!-- </button>-->
<!-- <button (click)="deleteWorks()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Delete work</span>-->
<!-- </button>-->
<!-- <button (click)="closeWorkModal()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Cancel</span>-->
<!-- </button>-->
<!-- </div>-->
<!-- </div>-->
<!---->
<!-- <div *ngIf="showLoading" class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">-->
<!-- <span class="loading-gif uk-align-center"></span>-->
<!-- </div>-->
<!---->
<!-- <div *ngIf="requestGrant" class="uk-margin-large-top">-->
<!-- <div>{{requestGrantMessage}}</div>-->
<!-- <button (click)="openGrantWindow()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-small-top uk-margin-left uk-button-primary">-->
<!-- <span>Grant OpenAIRE</span>-->
<!-- </button>-->
<!-- </div>-->
<!-- -->
<!-- </div>-->
<!-- </modal-alert>-->
<!-- <modal-alert #messageModal [classTitle]="'landing-modal-header uk-padding-small'"-->
<!-- [classBody]="'landing-modal uk-padding-remove'">-->
<!-- <div class="uk-text-center uk-padding-small">-->
<!-- <div>{{message}}</div>-->
<!-- <button (click)="closeMessageModal()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin uk-button-primary uk-float-right">-->
<!-- <span>OK</span>-->
<!-- </button>-->
<!-- </div>-->
<!-- </modal-alert>-->
<!--<button (click)="openGrantWindow()" type="submit"-->
<!-- class="uk-button uk-padding-small uk-padding-remove-vertical uk-button-default">-->
<!-- <span>Test grant</span>-->
<!--</button>-->
<!-- <a [href]="this.tokenUrl" target="_blank" class="uk-button uk-button-default">-->
<!-- Test-->
<!-- </a>-->
`
})
export class OrcidWorkComponent {
@Input() resultId: string = "dedup_wf_001::35c93a04a93b87f3a5954c1387aa7588";
@Input() resultLandingInfo: ResultLandingInfo;
@Input() pids: string = "";
@Input() type: string;
@Input() putCodes: string[];
@Input() givenPutCode: boolean = false;
@Input() pageType: string = "search";
public subscriptions: Subscription[] = [];
@ViewChild('workModal') workModal;
@ViewChild('saveWorkModal') saveWorkModal;
@ViewChild('grantModal') grantModal;
@ViewChild('messageModal') messageModal;
public requestGrant: boolean = false;
public requestGrantMessage: string = "Please grant OpenAIRE to access and update your ORCID record and works.";
private clientId: string = "APP-A5M3KTX6NCN67L91";
private tokenUrl: string;
public message: string = "";
public showLoading: boolean = false;
public works: any[] = [];
public window: any;
constructor(private route: ActivatedRoute,
private _router: Router,
private orcidService: OrcidService,
private resultLandingService: ResultLandingService) {
if(typeof location !== undefined) {
console.debug(location);
this.tokenUrl = "https://sandbox.orcid.org/oauth/authorize?"
+ "client_id="+this.clientId
// + "&response_type=code&scope=/activities/update"
+ "&response_type=code&scope=/authenticate /activities/update /person/update /read-limited"
+ "&redirect_uri="+location.origin+"/orcid";
}
}
ngOnInit() {
if(!this.givenPutCode) {
this.getPutCode();
}
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
console.debug("subscription closing...");
subscription.unsubscribe();
}
});
}
openGrantWindow() {
// this.tokenUrl = location.origin+"/orcid";
this.window = window.open(this.tokenUrl, '_blank',
'location=yes,height=600,width=500,left=500,top=100,scrollbars=yes,status=yes');
// this.requestGrant = false;
console.debug("before closing");
this.closeWorkModal();
console.debug("should be closed");
// var timer = setInterval(function() {
// console.debug("check");
// if(this.window.closed) {
// clearInterval(timer);
// console.debug('closed');
// }
// }, 1000);
let self = this;
window.onmessage = function (ev) {
console.debug("onmessage", ev);
if(ev.isTrusted && ev.origin !== location.origin && ev.data !== 'success')
return;
self.requestGrant = false;
UIkit.notification({
message: '<strong>Thank you for connecting your ORCID iD with OpenAIRE!<strong>',
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
self.saveWorkPreparation();
};
// window.addEventListener("message", (eventt) => {
// // if(event.origin !== location.origin+"/orcid")
// // return;
// console.debug("EVEEEENT", eventt);
// }, false);
// this.window.onbeforeunload = function () {
// console.debug("ONBEFOREUNLOAD!!!!");
// UIkit.notification({
// message: '<strong>Thank you for connecting your ORCID iD with OpenAIRE!<strong>',
// status: 'success',
// timeout: 6000,
// pos: 'bottom-right'
// });
// }
}
private getPutCode() {
console.debug(this.pids);
this.subscriptions.push(this.orcidService.getPutCode(this.pids).subscribe(
putCodes => {
this.putCodes = putCodes;
console.debug(this.putCodes);
}, error => {
}
))
}
private saveWorkPreparation() {
if(this.requestGrant) {
this.openWorkModal("Edit work in your ORCID record");
} else {
this.showLoading = true;
if (this.resultLandingInfo) {
this.saveWork();
} else {
this.subscriptions.push(this.resultLandingService.getResultLandingInfo(this.resultId, null, this.type, null, properties).subscribe(
resultLandingInfo => {
this.resultLandingInfo = resultLandingInfo;
if (this.resultLandingInfo && this.resultLandingInfo.identifiers) {
let pidsArray: string[] = [];
for (let key of Array.from(this.resultLandingInfo.identifiers.keys())) {
pidsArray = pidsArray.concat(this.resultLandingInfo.identifiers.get(key));
}
this.pids = pidsArray.join();
}
this.saveWork();
},
error => {
this.handleError(error, "There was an error adding this work to your ORCID record. Please try again later.");
console.error("Error getting landing info: ", error);
}
))
}
}
}
private saveWork() {
this.subscriptions.push(this.orcidService.saveWork(this.resultLandingInfo, this.pids).subscribe(
response => {
console.debug(response);
// for testing only
// this.openWorkModal("Add work in your ORCID record");
// this.requestGrant = true;
// this.requestGrantMessage = "Please grant OpenAIRE to access and update your ORCID record and works.";
if(response == null) {
this.handleError(null, "There was an error adding this work to your ORCID record. Please try again later.");
console.error("Error posting landing info: null");
} else {
//this.work = this.orcidService.parse(this.resultLandingInfo);
//this.work['put-code'] = response;
this.works.push(response);
this.putCodes.push(this.works[this.works.length - 1]['put-code']);
// this.closeWorkModal();
this.message = "You have successfully added this work in your ORCID record!";
// this.openMessageModal("Work added successfully");
UIkit.notification({
message: '<strong>You have successfully added this work in your ORCID record!<strong>',
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
this.showLoading = false;
}
},
error => {
this.handleError(error, "There was an error adding this work to your ORCID record. Please try again later.");
console.error("Error posting landing info", error);
}
));
}
// private updateWork() {
// this.subscriptions.push(this.orcidService.updateWork(this.resultLandingInfo, this.putCode).subscribe(
// response => {
// console.debug(response);
// //this.work = this.orcidService.parse(this.resultLandingInfo);
// //this.work['put-code'] = response;
// this.work = response;
// },
// error => {
// console.error("Error updating landing info", error);
// }
// ));
// }
private getWorks() {
this.showLoading = true;
this.subscriptions.push(this.orcidService.getWorks(this.pids).subscribe(
response => {
console.debug(response);
this.works = response;
if(this.works) {
this.works.forEach(work => this.putCodes.push(work['put-code']));
} else {
this.putCodes = [];
}
this.closeWorkModal();
this.showLoading = false;
},
error => {
this.handleError(error, "There was an error getting this work from your ORCID record. Please try again later.");
console.error("Error getting work", error);
}
));
}
private deleteWorks() {
// let put_code;// = this.testingPutCode;
// if(this.work && this.work['put-code']) {
// put_code = this.work['put-code'];
// }
if(this.requestGrant) {
this.openWorkModal("Edit work in your ORCID record");
} else {
this.showLoading = true;
this.subscriptions.push(this.orcidService.deleteWorks(this.putCodes).subscribe(
deletedPutCodes => {
console.debug(deletedPutCodes);
let deletedAll: boolean = true;
if (deletedPutCodes) {
for (let i = 0; i < deletedPutCodes.length; i++) {
let deletedPutCode = deletedPutCodes[i];
if (deletedPutCode == null) {
deletedAll = false;
} else {
this.works.splice(i, 1);
this.putCodes.splice(i, 1);
}
}
} else {
deletedAll = false;
}
if (!deletedAll) {
this.handleError(null, "There was an error deleting this work from your ORCID record. Please try again later.");
console.error("Error deleting landing info: null");
} else {
// this.closeWorkModal();
this.message = "You have successfully deleted this work from your ORCID record!";
// this.openMessageModal("Work deleted successfully");
UIkit.notification({
message: '<strong>You have successfully deleted this work from your ORCID record!<strong>',
status: 'success',
timeout: 6000,
pos: 'bottom-right'
});
this.showLoading = false;
}
},
error => {
this.handleError(error, "There was an error deleting this work to your ORCID record. Please try again later.");
console.error("Error deleting work", error);
}
));
}
}
openWorkModal(title: string) {
this.workModal.cancelButton = false;
this.workModal.okButton = false;
this.workModal.alertTitle = title;
this.workModal.open();
}
closeWorkModal() {
console.debug("closeWorkModal");
this.workModal.cancel();
}
openMessageModal(title: string) {
this.messageModal.cancelButton = false;
this.messageModal.okButton = false;
this.messageModal.alertTitle = title;
this.messageModal.open();
}
closeMessageModal() {
this.messageModal.cancel();
}
handleError(error, errorMsg: string) {
if(error && error.status == "401") {
this.openWorkModal("Edit work in your ORCID record");
this.requestGrant = true;
this.requestGrantMessage = "Please grant OpenAIRE to access and update your ORCID record and works. " +
"If you have already granted OpenAIRE, you just need to login again to ORCID!";
} else if(error && error.status == "403") {
this.openWorkModal("Edit work in your ORCID record");
this.requestGrant = true;
this.requestGrantMessage = "Please login again to ORCID."
// this.openGrantModal();
} else {
this.message = errorMsg;
UIkit.notification({
message: '<strong>'+this.message+'<strong>',
status: 'warning',
timeout: 6000,
pos: 'bottom-right'
});
// this.openMessageModal("An error occured");
}
this.showLoading = false;
}
}

267
orcid/orcid.component.ts Normal file
View File

@ -0,0 +1,267 @@
import { Component } from '@angular/core';
import {ActivatedRoute, Router} from "@angular/router";
import {Subscriber, Subscription} from "rxjs";
import {OrcidService} from "./orcid.service";
import {ResultLandingService} from "../landingPages/result/resultLanding.service";
import {ResultLandingInfo} from "../utils/entities/resultLandingInfo";
import {properties} from "../../../environments/environment";
@Component({
selector: 'orcid',
template: `
<!-- <div class="uk-section uk-container">-->
<!-- <div *ngIf="!testingUserRecord" class="uk-margin-small-top">Testing user ORCID iD: {{testingUserOrcid}}</div>-->
<!-- <div *ngIf="testingUserToken">-->
<!--&lt;!&ndash; <div>Testing user token: {{testingUserToken}}</div>&ndash;&gt;-->
<!-- <button (click)="getRecord()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-margin-small-top uk-button-primary">-->
<!-- <span>Get record</span>-->
<!-- </button>-->
<!-- <div *ngIf="testingUserRecord" class="uk-margin-small-top">{{testingUserRecord | json}}</div>-->
<!-- <button *ngIf="!work" (click)="getLanding()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-margin-small-top uk-button-primary">-->
<!-- <span>Get landing and post work</span>-->
<!-- </button>-->
<!--&lt;!&ndash; <div *ngIf="resultLandingInfo" class="uk-margin-small-top">{{resultLandingInfo | json}}</div>&ndash;&gt;-->
<!-- <button *ngIf="!work" (click)="getWork()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-margin-small-top uk-button-primary">-->
<!-- <span>Get work</span>-->
<!-- </button>-->
<!-- <div *ngIf="work" class="uk-margin-small-top">{{work | json}}</div>-->
<!-- <button *ngIf="work" (click)="deleteWork()" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-margin-small-top uk-button-primary">-->
<!-- <span>Delete work</span>-->
<!-- </button>-->
<!--&lt;!&ndash; <button (click)="getWorks()" type="submit"&ndash;&gt;-->
<!--&lt;!&ndash; class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-margin-small-top uk-button-primary">&ndash;&gt;-->
<!--&lt;!&ndash; <span>Get works</span>&ndash;&gt;-->
<!--&lt;!&ndash; </button>&ndash;&gt;-->
<!--&lt;!&ndash; <div *ngIf="works" class="uk-margin-small-top">{{works | json}}</div>&ndash;&gt;-->
<!-- </div>-->
<!-- <div *ngIf="!testingUserToken" class="uk-flex uk-flex-middle">-->
<!-- No token for testing user found. You need to grant access OpenAIRE.-->
<!-- <a href="{{tokenUrl}}" type="submit"-->
<!-- class="uk-button uk-padding uk-padding-remove-vertical uk-margin-left uk-button-primary">-->
<!-- <span>Get code and token</span>-->
<!-- </a>-->
<!-- </div>-->
<!-- </div>-->
<div class="uk-section uk-container">
<div *ngIf="orcidMessage">{{orcidMessage}}</div>
<div *ngIf="message" [innerHTML]="message"></div>
<div *ngIf="showLoading" class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">
<span class="loading-gif uk-align-center"></span>
</div>
</div>
`
})
export class OrcidComponent {
private clientId: string = "APP-A5M3KTX6NCN67L91";
//Client secret: 96b20d71-ae06-4286-bb00-9172536c1ad4
public tokenUrl: string = "";//"https://sandbox.orcid.org/oauth/authorize?client_id="+this.clientId+"&response_type=code&scope=/authenticate&redirect_uri="+location.href;
public testingUserToken: any = "ac2e24e2-cd7e-4874-8cb8-d56395b9f3e2";// = "70a0274a-5b28-49dc-b6fd-2b427727a0da";// = "94634687-f5ea-4a0d-91ab-da8268287f72";
public testingUserOrcid: string = "0000-0001-9541-4617";
public testingUserRecord: any;
public resultId: string = "dedup_wf_001::35c93a04a93b87f3a5954c1387aa7588";
public testingPutCode: string = "1167642";
// invalid:
//code: gpq2pG
// {"access_token":"c4a81d38-4a32-4160-887d-9b6f39ce2d75","token_type":"bearer","refresh_token":"0ba698e9-f73b-40ca-a0c3-f7b8e1123f3c","expires_in":631138518,"scope":"/authenticate","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"f4d8f230-fe1a-4d4e-af52-6ee67556ad2c","token_type":"bearer","refresh_token":"dc041582-33f4-476a-851d-f8d7e44de84c","expires_in":631138518,"scope":"/authenticate","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"91eced53-0c44-4e5b-b49e-b32cc4548988","token_type":"bearer","refresh_token":"d9c35f21-1f67-4c1a-99af-fc445ead37c4","expires_in":631138518,"scope":"/authenticate","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"c953699e-06bf-41a3-98a2-4ad3241a6592","token_type":"bearer","refresh_token":"75341fe0-26f6-41b8-85b0-3add39d7891e","expires_in":631138518,"scope":"/authenticate /read-limited /activities/update /person/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"3ad4cadd-3429-4a6d-acc8-95fecf110917","token_type":"bearer","refresh_token":"ff0d26c1-6f42-4f25-8eae-51b84b83f0cc","expires_in":631138518,"scope":"/authenticate /read-limited /activities/update /person/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"f77deae6-a8cd-4070-b409-eb459ed22cd1","token_type":"bearer","refresh_token":"70c6ae8f-0de6-4ebf-ac0e-409beda5d17f","expires_in":631138518,"scope":"/authenticate","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"d5c7d36e-fdbb-44b4-bb4e-1364286ba73a","token_type":"bearer","refresh_token":"db85dc40-c8dc-4ed5-81de-e98fb8d35228","expires_in":631138518,"scope":"/authenticate /read-limited /activities/update /person/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"94634687-f5ea-4a0d-91ab-da8268287f72","token_type":"bearer","refresh_token":"1d4c01f2-a1ef-4f01-8187-3fc26cbc5b78","expires_in":631138518,"scope":"/authenticate /read-limited /activities/update /person/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"70a0274a-5b28-49dc-b6fd-2b427727a0da","token_type":"bearer","refresh_token":"b973c6fd-99b3-415e-af0c-6944500f8af3","expires_in":631138518,"scope":"/activities/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"d1847264-a7e0-4f26-98e5-f193362ee7e2","token_type":"bearer","refresh_token":"2d1e1bfe-54d0-4e7c-984b-8af16609f6ae","expires_in":631138518,"scope":"/authenticate /read-limited /activities/update /person/update","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
// {"access_token":"77c17e47-bbe7-4a05-a0e6-5c7920a8cc26","token_type":"bearer","refresh_token":"6ae41ee9-ef94-4f8b-bb08-a241e720d3c5","expires_in":631138518,"scope":"/authenticate","name":"OpenAIRE OpenAIRE","orcid":"0000-0001-9541-4617"}
public subscriptions: Subscription[] = [];
public resultLandingInfo: ResultLandingInfo;
public work: any;
public works: any;
public showLoading: boolean = false;
public message: string = "";
public orcidMessage: string = "";
constructor(private route: ActivatedRoute,
private _router: Router,
private orcidService: OrcidService,
private resultLandingService: ResultLandingService) {
if(typeof location !== undefined) {
console.debug(location);
this.tokenUrl = "https://sandbox.orcid.org/oauth/authorize?"
+ "client_id="+this.clientId
// + "&response_type=code&scope=/activities/update"
+ "&response_type=code&scope=/authenticate /activities/update /person/update /read-limited"
+ "&redirect_uri="+location.origin+"/orcid";
}
}
ngOnInit() {
this.subscriptions.push(this.route.queryParams.subscribe(params => {
if (params['code']) {
this.getToken(params['code']);
} else if(params['error']) {
this.showLoading = false;
this.orcidMessage = params['error_description'];
this.message = "<div>An error occured while trying to grant access OpenAIRE. </div>" +
"<div>Please close this window and try again!</div>";
} else {
this.message = "No code provided to connect your ORCID with OpenAIRE. Please try again!"
}
}));
}
ngOnDestroy() {
this.subscriptions.forEach(subscription => {
if (subscription instanceof Subscriber) {
console.debug("subscription closing...");
subscription.unsubscribe();
}
});
}
// the following method uses client ID and client Secret, which are sessitive data.
// Our API should return the response, without revealing the call to ORCID.
private getToken(code: string) {
this.showLoading = true;
this.orcidService.getToken(code).subscribe(
tokens => {
console.debug(tokens);
this.testingUserToken = tokens;
if(tokens == null) {
this.showLoading = false;
this.message = "An error occured while trying to connect your ORCID iD with OpenAIRE. Please try again!";
} else {
window.opener.postMessage("success");
window.close();
this.message = "Thank you for connecting your ORCID iD with OpenAIRE! Please close this window and continue!";
}
},
error => {
console.error("Error getting token from code: "+code, error);
this.message = "An error occured while trying to connect your ORCID iD with OpenAIRE. Please try again!";
},
() => {
this.showLoading = false;
}
)
}
private getRecord() {
//this.orcidService.getMyRecord(this.testingUserToken, this.testingUserOrcid).subscribe(
this.subscriptions.push(this.orcidService.getRecord().subscribe(
record => {
this.testingUserRecord = record;
console.debug(record);
},
error => {
console.error("Error getting record info for ORCID iD: "+this.testingUserOrcid + " with token: "+this.testingUserToken, error);
}
));
}
private getLanding() {
this.subscriptions.push(this.resultLandingService.getResultLandingInfo(this.resultId, null, "publication", null, properties).subscribe(
data => {
this.resultLandingInfo = data;
this.postWork();
console.debug(this.resultLandingInfo);
},
error => {
console.error("Error getting landing info for publication id: "+this.resultId, error);
}
));
}
private postWork() {
let pids: string[] = [];
if(this.resultLandingInfo && this.resultLandingInfo.identifiers) {
for (let key of Array.from(this.resultLandingInfo.identifiers.keys())) {
pids = pids.concat(this.resultLandingInfo.identifiers.get(key));
}
}
this.subscriptions.push(this.orcidService.saveWork(this.resultLandingInfo, pids.join()).subscribe(
response => {
console.debug(response);
//this.work = this.orcidService.parse(this.resultLandingInfo);
//this.work['put-code'] = response;
this.work = response;
},
error => {
console.error("Error posting landing info", error);
}
));
}
// private updateWork() {
// this.subscriptions.push(this.orcidService.updateWork(this.resultLandingInfo, this.testingUserOrcid, this.testingPutCode).subscribe(
// response => {
// console.debug(response);
// //this.work = this.orcidService.parse(this.resultLandingInfo);
// //this.work['put-code'] = response;
// this.work = response;
// },
// error => {
// console.error("Error updating landing info", error);
// }
// ));
// }
// private getWorks() {
// this.subscriptions.push(this.orcidService.getWorks().subscribe(
// response => {
// console.debug(response);
// this.works = response;
// },
// error => {
// console.error("Error getting works", error);
// }
// ));
// }
// private getWork() {
// this.subscriptions.push(this.orcidService.getWork(this.resultId).subscribe(
// response => {
// console.debug(response);
// this.work = response;
// },
// error => {
// console.error("Error getting work", error);
// }
// ));
// }
private deleteWork() {
let put_code = this.testingPutCode;
if(this.work && this.work['put-code']) {
put_code = this.work['put-code'];
}
this.subscriptions.push(this.orcidService.deleteWork(put_code).subscribe(
response => {
console.debug(response);
this.work = null;
},
error => {
console.error("Error deleting work", error);
}
));
}
}

34
orcid/orcid.module.ts Normal file
View File

@ -0,0 +1,34 @@
import { NgModule, ModuleWithProviders } from '@angular/core';
import { CommonModule } from '@angular/common';
import {RouterModule} from "@angular/router";
import {OrcidComponent} from './orcid.component';
import {OrcidService} from "./orcid.service";
import {FreeGuard} from '../login/freeGuard.guard';
import {PreviousRouteRecorder} from "../utils/piwik/previousRouteRecorder.guard";
import {OrcidWorkComponent} from "./orcid-work.component";
import {AlertModalModule} from "../utils/modal/alertModal.module";
import {ResultLandingService} from "../landingPages/result/resultLanding.service";
import {LoadingModule} from "../utils/loading/loading.module";
@NgModule({
imports: [
CommonModule, RouterModule, AlertModalModule, LoadingModule
],
declarations: [
OrcidComponent,
OrcidWorkComponent
],
providers:[
FreeGuard, PreviousRouteRecorder,
OrcidService, ResultLandingService
],
exports: [
OrcidComponent,
OrcidWorkComponent
]
})
export class OrcidModule{}

96
orcid/orcid.service.ts Normal file
View File

@ -0,0 +1,96 @@
import {Injectable} from "@angular/core";
import {HttpClient} from "@angular/common/http";
import {map} from "rxjs/operators";
import {ResultLandingInfo} from "../utils/entities/resultLandingInfo";
import {CustomOptions} from "../services/servicesUtils/customOptions.class";
import {WorkV3_0} from "./orcidWork";
import {encode, toUnicode} from "punycode";
import {Observable} from "rxjs";
import {properties} from "../../../environments/environment";
@Injectable()
export class OrcidService {
constructor(private http: HttpClient) {}
getPutCode(pids: string) {
let url: string = properties.orcidAPIURL+"put-code?pids="+pids;
return this.http.get<string[]>(url, CustomOptions.registryOptions());
}
getPutCodes(pids: string[][]) {
let url: string = properties.orcidAPIURL+"put-codes";
return this.http.post<string[][]>(url, JSON.stringify(pids), CustomOptions.registryOptions());
}
getToken(code: string) {
// let url: string = "https://sandbox.orcid.org/oauth/token";
// let clientId: string = "APP-A5M3KTX6NCN67L91";
// let clientSecret: string = "96b20d71-ae06-4286-bb00-9172536c1ad4";
// let body: string = "client_id="+clientId+"&client_secret="+clientSecret+"&grant_type=authorization_code&code="+code+"&redirect_uri=http://duffy.di.uoa.gr:4300";
//let body: string = "client_id="+clientId+"&client_secret="+clientSecret+"&grant_type=authorization_code&code="+code;
// console.debug(JSON.stringify(body));
// console.debug(url);
// return this.http.post(url, JSON.stringify(body));
//.pipe(catchError(this.handleError));
console.debug(code);
let url: string = properties.orcidAPIURL+"token/save?code="+code;
return this.http.get<string>(url, CustomOptions.registryOptions());
}
getRecord() {
let url: string = properties.orcidAPIURL+"record";
return this.http.get(url, CustomOptions.registryOptions());
}
saveWork(resultLandingInfo: ResultLandingInfo, pids: string) {
let work = WorkV3_0.resultLandingInfoConvert(resultLandingInfo, null);
let result = {
"pids": pids.split(","),
"work": work
};
let url: string = properties.orcidAPIURL+"work/save";
return this.http.post<any>(url, JSON.stringify(result), CustomOptions.registryOptions())
.pipe(map(res => {
console.debug(res);
if(!res) {
return null;
}
work['put-code'] = +res;
return work;
}));
}
updateWork(resultLandingInfo: ResultLandingInfo, /*orcid: string,*/ putCode: string) {
let work = WorkV3_0.resultLandingInfoConvert(resultLandingInfo, putCode);
// let url: string = "http://duffy.di.uoa.gr:8080/uoa-orcid-service/orcid/"+orcid+"work/"+putCode;
let url: string = properties.orcidAPIURL+"work/update/"+putCode;
return this.http.post(url, JSON.stringify(work), CustomOptions.registryOptions())
.pipe(map(res => work));
}
// getWorks() {
// let url: string = "http://duffy.di.uoa.gr:8080/uoa-orcid-service/orcid/works?orcid=0000-0001-9541-4617";
// return this.http.get(url, CustomOptions.registryOptions());
// }
getWorks(pids: string) {
let url: string = "http://duffy.di.uoa.gr:8080/uoa-orcid-service/orcid/work?orcid=0000-0001-9541-4617&pids="+pids;
return this.http.get<any[]>(url, CustomOptions.registryOptions());
}
deleteWork(putCode: string) {
let url: string = properties.orcidAPIURL+"work/"+putCode+"/delete";
return this.http.delete(url, CustomOptions.registryOptions());
}
deleteWorks(putCodes: string[]) {
let url: string = properties.orcidAPIURL+"works/delete";
return this.http.post<string[]>(url, JSON.stringify(putCodes), CustomOptions.registryOptions());
}
getLocalWorks() {
let url: string = properties.orcidAPIURL+"works/local";
return this.http.get<any[]>(url, CustomOptions.registryOptions());
}
}

292
orcid/orcidWork.ts Normal file
View File

@ -0,0 +1,292 @@
import {ResultLandingInfo} from "../utils/entities/resultLandingInfo";
export class WorkV3_0 {
// automatically filled by orcid?
"created-date" ?: CreatedDateV3_0;
"last-modified-date" ?: LastModifiedDateV3_0;
source ?: SourceV3_0;
"put-code" ?: number;
path ?: string; // not sent
title ?: WorkTitleV3_0;
"journal-title" ?: TitleV3_0;
"short-description" ?: string;
citation ?: Citation; // not sent
type ?: string;// = ['annotation', 'artistic-performance', 'book-chapter', 'book-review', 'book', 'conference-abstract', 'conference-paper', 'conference-poster', 'data-set', 'dictionary-entry', 'disclosure', 'dissertation-thesis', 'edited-book', 'encyclopedia-entry', 'invention', 'journal-article', 'journal-issue', 'lecture-speech', 'license', 'magazine-article', 'manual', 'newsletter-article', 'newspaper-article', 'online-resource', 'other', 'patent', 'physical-object', 'preprint', 'registered-copyright', 'report', 'research-technique', 'research-tool', 'software', 'spin-off-company', 'standards-and-policy', 'supervised-student-publication', 'technical-standard', 'test', 'trademark', 'translation', 'website', 'working-paper', 'undefined'],
"publication-date" ?: PublicationDateV3_0;
"external-ids" ?: ExternalIDsV3_0;
url ?: UrlV3_0; // not sent - maybe url to landing with ?pid=...?
contributors ?: WorkContributorsV3_0;
"language-code" ?: string; // not sent // = ['ab', 'aa', 'af', 'ak', 'sq', 'am', 'ar', 'an', 'hy', 'as', 'av', 'ae', 'ay', 'az', 'bm', 'ba', 'eu', 'be', 'bn', 'bh', 'bi', 'bs', 'br', 'bg', 'my', 'ca', 'ch', 'ce', 'zh_CN', 'zh_TW', 'cu', 'cv', 'kw', 'co', 'cr', 'hr', 'cs', 'da', 'dv', 'nl', 'dz', 'en', 'eo', 'et', 'ee', 'fo', 'fj', 'fi', 'fr', 'fy', 'ff', 'gl', 'lg', 'ka', 'de', 'el', 'kl', 'gn', 'gu', 'ht', 'ha', 'iw', 'hz', 'hi', 'ho', 'hu', 'is', 'io', 'ig', 'in', 'ia', 'ie', 'iu', 'ik', 'ga', 'it', 'ja', 'jv', 'kn', 'kr', 'ks', 'kk', 'km', 'ki', 'rw', 'ky', 'kv', 'kg', 'ko', 'ku', 'kj', 'lo', 'la', 'lv', 'li', 'ln', 'lt', 'lu', 'lb', 'mk', 'mg', 'ms', 'ml', 'mt', 'gv', 'mi', 'mr', 'mh', 'mo', 'mn', 'na', 'nv', 'ng', 'ne', 'nd', 'se', 'no', 'nb', 'nn', 'ny', 'oc', 'oj', 'or', 'om', 'os', 'pi', 'pa', 'fa', 'pl', 'pt', 'ps', 'qu', 'rm', 'ro', 'rn', 'ru', 'sm', 'sg', 'sa', 'sc', 'gd', 'sr', 'sn', 'ii', 'sd', 'si', 'sk', 'sl', 'so', 'nr', 'st', 'es', 'su', 'sw', 'ss', 'sv', 'tl', 'ty', 'tg', 'ta', 'tt', 'te', 'th', 'bo', 'ti', 'to', 'ts', 'tn', 'tr', 'tk', 'tw', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'cy', 'wo', 'xh', 'ji', 'yo', 'za', 'zu'],
country ?: CountryV3_0; // not sent
visibility ?: string; // always public? // = ['limited', 'registered-only', 'public']
public static resultLandingInfoConvert(resultLandingInfo: ResultLandingInfo, putCode: string) : WorkV3_0 {
let work: WorkV3_0 = {};
// let work = {};
// created-date (CreatedDateV3_0, optional),
// last-modified-date (LastModifiedDateV3_0, optional),
//
// work["source"] = {
// "source-orcid": {
// "uri": "https://sandbox.orcid.org/0000-0001-9541-4617",
// "path": "0000-0001-9541-4617",
// "host": "sandbox.orcid.org"
// }
// };
// work["source-client-id"] = null;
// work["source-name"] = {
// "value": "OpenAIRE OpenAIRE"
// };
// work["assertion-origin-orcid"] = null;
// work["assertion-origin-client-id"] = null;
// work["assertion-origin-name"] = null;
//
console.debug("putCode: "+putCode);
if(putCode) {
work['put-code'] = +putCode;
}
// path (string, optional),
if(resultLandingInfo.title || resultLandingInfo.subtitle) {
let title = {};
if(resultLandingInfo.title ) {
title['title'] = {"value": resultLandingInfo.title};
}
if(resultLandingInfo.subtitle) {
title['subtitle'] = { "value": resultLandingInfo.subtitle };
}
// translated-title
work['title'] = title;
}
if(resultLandingInfo.journal && resultLandingInfo.journal.journal) {
work['journal-title'] = { "value": resultLandingInfo.journal.journal };
}
if(resultLandingInfo.description) {
work['short-description'] = resultLandingInfo.description;
}
// citation (Citation, optional),
if(resultLandingInfo.types) {
work['type'] = "other";//resultLandingInfo.types[0];
}
if(resultLandingInfo.date || resultLandingInfo.dateofacceptance) {
if(resultLandingInfo.dateofacceptance) {
work['publication-date'] = {
"year": { "value": ('0' + resultLandingInfo.dateofacceptance.getFullYear()).slice(-4) },
"month": { "value": ('0' + resultLandingInfo.dateofacceptance.getMonth()).slice(-2) },
"day": { "value": ('0' + resultLandingInfo.dateofacceptance.getDay()).slice(-2) }
}
} else {
work['publication-date'] = {
"year": { "value": resultLandingInfo.date+"" }
}
}
}
if(resultLandingInfo.identifiers) {
work['external-ids'] = { 'external-id': [] };
resultLandingInfo.identifiers.forEach(((values, key) => {
values.forEach(value => {
work['external-ids']['external-id'].push(
{
"external-id-type": key,
"external-id-value": value,
"external-id-relationship": "self"
}
)
})
}))
}
// url (UrlV3_0, optional),
if(resultLandingInfo.authors) {
work['contributors'] = { 'contributor': [] };
resultLandingInfo.authors.forEach((author, index) => {
let contributor = {};
if(author.orcid) {
contributor["contributor-orcid"] =
{
// "uri": "string",
"path": author.orcid
// "host": "string"
}
}
if(author.fullName) {
contributor["credit-name"] =
{
"value": author.fullName
}
}
// "contributor-email": {
// "value": "string"
// },
contributor["contributor-attributes"] = {
"contributor-sequence": index == 0 ? "first" : "additional",
"contributor-role": "author"
};
work['contributors']['contributor'].push(contributor);
})
}
if(resultLandingInfo.languages) {
// work["language-code"] = "";
}
if(resultLandingInfo.countries) {
// work["country"] = {
// "value": "AF"
// }
}
// visibility (string, optional) = ['limited', 'registered-only', 'public']
console.debug(work);
return work;
}
}
export interface CreatedDateV3_0 {
value ?: string;//read only)
}
export interface LastModifiedDateV3_0 {
value ?: string;//read only)
}
export interface SourceV3_0 {
"source-orcid" ?: SourceOrcidV3_0;
"source-client-id" ?: SourceClientIdV3_0;
"source-name" ?: SourceNameV3_0;
"assertion-origin-orcid" ?: SourceOrcidV3_0;
"assertion-origin-client-id" ?: SourceClientIdV3_0;
"assertion-origin-name" ?: SourceNameV3_0;
}
export interface WorkTitleV3_0 {
title ?: TitleV3_0;
subtitle ?: SubtitleV3_0;
"translated-title" ?: TranslatedTitleV3_0;
}
export interface TitleV3_0 {
value ?: string;
}
export interface Citation {
"citation-type": string;//= ['formatted-unspecified', 'bibtex', 'formatted-apa', 'formatted-harvard', 'formatted-ieee', 'formatted-mla', 'formatted-vancouver', 'formatted-chicago', 'ris'],
"citation-value": string;
}
export interface PublicationDateV3_0 {
year: YearV3_0;
month ?: MonthV3_0;
day ?: DayV3_0;
}
export interface ExternalIDsV3_0 {
"external-id" ?: ExternalIDV3_0[];
}
export interface UrlV3_0 {
value ?: string;
}
export interface WorkContributorsV3_0 {
contributor ?: ContributorV3_0[];
}
export interface CountryV3_0 {
value ?: string;// = ['AF', 'AX', 'AL', 'DZ', 'AS', 'AD', 'AO', 'AI', 'AQ', 'AG', 'AR', 'AM', 'AW', 'AU', 'AT', 'AZ', 'BS', 'BH', 'BD', 'BB', 'BY', 'BE', 'BZ', 'BJ', 'BM', 'BT', 'BO', 'BQ', 'BA', 'BW', 'BV', 'BR', 'IO', 'BN', 'BG', 'BF', 'BI', 'KH', 'CM', 'CA', 'CV', 'KY', 'CF', 'TD', 'CL', 'CN', 'CX', 'CC', 'CO', 'KM', 'CG', 'CD', 'CK', 'CR', 'CI', 'HR', 'CU', 'CW', 'CY', 'CZ', 'DK', 'DJ', 'DM', 'DO', 'EC', 'EG', 'SV', 'GQ', 'ER', 'EE', 'ET', 'FK', 'FO', 'FJ', 'FI', 'FR', 'GF', 'PF', 'TF', 'GA', 'GM', 'GE', 'DE', 'GH', 'GI', 'GR', 'GL', 'GD', 'GP', 'GU', 'GT', 'GG', 'GN', 'GW', 'GY', 'HT', 'HM', 'VA', 'HN', 'HK', 'HU', 'IS', 'IN', 'ID', 'IR', 'IQ', 'IE', 'IM', 'IL', 'IT', 'JM', 'JP', 'JE', 'JO', 'KZ', 'KE', 'KI', 'KP', 'KR', 'KW', 'KG', 'LA', 'LV', 'LB', 'LS', 'LR', 'LY', 'LI', 'LT', 'LU', 'MO', 'MK', 'MG', 'MW', 'MY', 'MV', 'ML', 'MT', 'MH', 'MQ', 'MR', 'MU', 'YT', 'MX', 'FM', 'MD', 'MC', 'MN', 'ME', 'MS', 'MA', 'MZ', 'MM', 'NA', 'NR', 'NP', 'NL', 'NC', 'NZ', 'NI', 'NE', 'NG', 'NU', 'NF', 'MP', 'NO', 'OM', 'PK', 'PW', 'PS', 'PA', 'PG', 'PY', 'PE', 'PH', 'PN', 'PL', 'PT', 'PR', 'QA', 'RE', 'RO', 'RU', 'RW', 'BL', 'SH', 'KN', 'LC', 'MF', 'PM', 'VC', 'WS', 'SM', 'ST', 'SA', 'SN', 'RS', 'SC', 'SL', 'SG', 'SX', 'SK', 'SI', 'SB', 'SO', 'ZA', 'GS', 'SS', 'ES', 'LK', 'SD', 'SR', 'SJ', 'SZ', 'SE', 'CH', 'SY', 'TJ', 'TZ', 'TH', 'TL', 'TG', 'TK', 'TO', 'TT', 'TN', 'TR', 'TM', 'TC', 'TV', 'UG', 'UA', 'AE', 'GB', 'US', 'UM', 'UY', 'UZ', 'VU', 'VE', 'VN', 'VG', 'VI', 'WF', 'EH', 'YE', 'ZM', 'ZW', 'TW', 'XK']
}
export interface SourceOrcidV3_0 {
uri ?: string;
path ?: string;
host ?: string;
}
export interface SourceClientIdV3_0 {
uri ?: string;
path ?: string;
host ?: string;
}
export interface SourceNameV3_0 {
value ?: string;
}
export interface SubtitleV3_0 {
value ?: string;
}
export interface TranslatedTitleV3_0 {
value ?: string;
"language-code": string;// = ['ab', 'aa', 'af', 'ak', 'sq', 'am', 'ar', 'an', 'hy', 'as', 'av', 'ae', 'ay', 'az', 'bm', 'ba', 'eu', 'be', 'bn', 'bh', 'bi', 'bs', 'br', 'bg', 'my', 'ca', 'ch', 'ce', 'zh_CN', 'zh_TW', 'cu', 'cv', 'kw', 'co', 'cr', 'hr', 'cs', 'da', 'dv', 'nl', 'dz', 'en', 'eo', 'et', 'ee', 'fo', 'fj', 'fi', 'fr', 'fy', 'ff', 'gl', 'lg', 'ka', 'de', 'el', 'kl', 'gn', 'gu', 'ht', 'ha', 'iw', 'hz', 'hi', 'ho', 'hu', 'is', 'io', 'ig', 'in', 'ia', 'ie', 'iu', 'ik', 'ga', 'it', 'ja', 'jv', 'kn', 'kr', 'ks', 'kk', 'km', 'ki', 'rw', 'ky', 'kv', 'kg', 'ko', 'ku', 'kj', 'lo', 'la', 'lv', 'li', 'ln', 'lt', 'lu', 'lb', 'mk', 'mg', 'ms', 'ml', 'mt', 'gv', 'mi', 'mr', 'mh', 'mo', 'mn', 'na', 'nv', 'ng', 'ne', 'nd', 'se', 'no', 'nb', 'nn', 'ny', 'oc', 'oj', 'or', 'om', 'os', 'pi', 'pa', 'fa', 'pl', 'pt', 'ps', 'qu', 'rm', 'ro', 'rn', 'ru', 'sm', 'sg', 'sa', 'sc', 'gd', 'sr', 'sn', 'ii', 'sd', 'si', 'sk', 'sl', 'so', 'nr', 'st', 'es', 'su', 'sw', 'ss', 'sv', 'tl', 'ty', 'tg', 'ta', 'tt', 'te', 'th', 'bo', 'ti', 'to', 'ts', 'tn', 'tr', 'tk', 'tw', 'ug', 'uk', 'ur', 'uz', 've', 'vi', 'vo', 'wa', 'cy', 'wo', 'xh', 'ji', 'yo', 'za', 'zu']
}
export interface YearV3_0 {
value ?: string;
}
export interface MonthV3_0 {
value ?: string;
}
export interface DayV3_0 {
value ?: string;
}
export interface ExternalIDV3_0 {
"external-id-type": string;
"external-id-value": string;
"external-id-normalized"?: TransientNonEmptyString;
"external-id-normalized-error"?: TransientError;
"external-id-url"?: UrlV3_0;
"external-id-relationship"?: string;// = ['part-of', 'self', 'version-of']}
}
export interface ContributorV3_0 {
"contributor-orcid" ?: ContributorOrcidV3_0;
"credit-name" ?: CreditNameV3_0;
"contributor-email" ?: ContributorEmailV3_0;
"contributor-attributes" ?: ContributorAttributesV3_0;
}
export interface TransientNonEmptyString {
value ?: string;
transient ?: boolean;
}
export interface TransientError {
"error-code": string;
"error-message": string;
transient: boolean;
}
export interface ContributorOrcidV3_0 {
uri ?: string;
path ?: string;
host ?: string;
}
export interface CreditNameV3_0 {
value ?: string;
}
export interface ContributorEmailV3_0 {
value ?: string;
}
export interface ContributorAttributesV3_0 {
"contributor-sequence": string;// = ['first', 'additional'],
"contributor-role": string;// = ['author', 'assignee', 'editor', 'chair-or-translator', 'co-investigator', 'co-inventor', 'graduate-student', 'other-inventor', 'principal-investigator', 'postdoctoral-researcher', 'support-staff']
}