mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-13 13:03:04 +00:00
Merge remote-tracking branch '4Science-bitbucket/CST-5338' into CST-5307
This commit is contained in:
@@ -38,19 +38,19 @@ import {CoreState} from "../core-state.model";
|
|||||||
* A private DataService implementation to delegate specific methods to.
|
* A private DataService implementation to delegate specific methods to.
|
||||||
*/
|
*/
|
||||||
class ResearcherProfileServiceImpl extends DataService<ResearcherProfile> {
|
class ResearcherProfileServiceImpl extends DataService<ResearcherProfile> {
|
||||||
protected linkPath = 'profiles';
|
protected linkPath = 'profiles';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected comparator: DefaultChangeAnalyzer<ResearcherProfile>) {
|
protected comparator: DefaultChangeAnalyzer<ResearcherProfile>) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,100 +61,178 @@ class ResearcherProfileServiceImpl extends DataService<ResearcherProfile> {
|
|||||||
@dataService(RESEARCHER_PROFILE)
|
@dataService(RESEARCHER_PROFILE)
|
||||||
export class ResearcherProfileService {
|
export class ResearcherProfileService {
|
||||||
|
|
||||||
dataService: ResearcherProfileServiceImpl;
|
dataService: ResearcherProfileServiceImpl;
|
||||||
|
|
||||||
responseMsToLive: number = 10 * 1000;
|
responseMsToLive: number = 10 * 1000;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected rdbService: RemoteDataBuildService,
|
protected rdbService: RemoteDataBuildService,
|
||||||
protected store: Store<CoreState>,
|
protected store: Store<CoreState>,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
protected halService: HALEndpointService,
|
protected halService: HALEndpointService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected http: HttpClient,
|
protected http: HttpClient,
|
||||||
protected router: Router,
|
protected router: Router,
|
||||||
protected comparator: DefaultChangeAnalyzer<ResearcherProfile>,
|
protected comparator: DefaultChangeAnalyzer<ResearcherProfile>,
|
||||||
protected itemService: ItemDataService,
|
protected itemService: ItemDataService,
|
||||||
protected configurationService: ConfigurationDataService ) {
|
protected configurationService: ConfigurationDataService ) {
|
||||||
|
|
||||||
this.dataService = new ResearcherProfileServiceImpl(requestService, rdbService, store, objectCache, halService,
|
this.dataService = new ResearcherProfileServiceImpl(requestService, rdbService, store, objectCache, halService,
|
||||||
notificationsService, http, comparator);
|
notificationsService, http, comparator);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the researcher profile with the given uuid.
|
* Find the researcher profile with the given uuid.
|
||||||
*
|
*
|
||||||
* @param uuid the profile uuid
|
* @param uuid the profile uuid
|
||||||
*/
|
*/
|
||||||
findById(uuid: string): Observable<ResearcherProfile> {
|
findById(uuid: string): Observable<ResearcherProfile> {
|
||||||
return this.dataService.findById(uuid, false)
|
return this.dataService.findById(uuid, false)
|
||||||
.pipe ( getFinishedRemoteData(),
|
.pipe ( getFinishedRemoteData(),
|
||||||
map((remoteData) => remoteData.payload));
|
map((remoteData) => remoteData.payload));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new researcher profile for the current user.
|
* Create a new researcher profile for the current user.
|
||||||
*/
|
*/
|
||||||
create(): Observable<RemoteData<ResearcherProfile>> {
|
create(): Observable<RemoteData<ResearcherProfile>> {
|
||||||
return this.dataService.create( new ResearcherProfile());
|
return this.dataService.create( new ResearcherProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a researcher profile.
|
* Delete a researcher profile.
|
||||||
*
|
*
|
||||||
* @param researcherProfile the profile to delete
|
* @param researcherProfile the profile to delete
|
||||||
*/
|
*/
|
||||||
delete(researcherProfile: ResearcherProfile): Observable<boolean> {
|
delete(researcherProfile: ResearcherProfile): Observable<boolean> {
|
||||||
return this.dataService.delete(researcherProfile.id).pipe(
|
return this.dataService.delete(researcherProfile.id).pipe(
|
||||||
getFirstCompletedRemoteData(),
|
getFirstCompletedRemoteData(),
|
||||||
tap((response: RemoteData<NoContent>) => {
|
tap((response: RemoteData<NoContent>) => {
|
||||||
if (response.isSuccess) {
|
if (response.isSuccess) {
|
||||||
this.requestService.setStaleByHrefSubstring(researcherProfile._links.self.href);
|
this.requestService.setStaleByHrefSubstring(researcherProfile._links.self.href);
|
||||||
}
|
}
|
||||||
|
}),
|
||||||
|
map((response: RemoteData<NoContent>) => response.isSuccess)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the item id related to the given researcher profile.
|
||||||
|
*
|
||||||
|
* @param researcherProfile the profile to find for
|
||||||
|
*/
|
||||||
|
findRelatedItemId( researcherProfile: ResearcherProfile ): Observable<string> {
|
||||||
|
return this.itemService.findByHref(researcherProfile._links.item.href, false)
|
||||||
|
.pipe (getFirstSucceededRemoteDataPayload(),
|
||||||
|
catchError((error) => {
|
||||||
|
console.debug(error);
|
||||||
|
return observableOf(null);
|
||||||
}),
|
}),
|
||||||
map((response: RemoteData<NoContent>) => response.isSuccess)
|
map((item) => item != null ? item.id : null ));
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the item id related to the given researcher profile.
|
* Change the visibility of the given researcher profile setting the given value.
|
||||||
*
|
*
|
||||||
* @param researcherProfile the profile to find for
|
* @param researcherProfile the profile to update
|
||||||
*/
|
* @param visible the visibility value to set
|
||||||
findRelatedItemId( researcherProfile: ResearcherProfile ): Observable<string> {
|
*/
|
||||||
return this.itemService.findByHref(researcherProfile._links.item.href, false)
|
setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable<ResearcherProfile> {
|
||||||
.pipe (getFirstSucceededRemoteDataPayload(),
|
|
||||||
catchError((error) => {
|
|
||||||
console.debug(error);
|
|
||||||
return observableOf(null);
|
|
||||||
}),
|
|
||||||
map((item) => item != null ? item.id : null ));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
const replaceOperation: ReplaceOperation<boolean> = {
|
||||||
* Change the visibility of the given researcher profile setting the given value.
|
path: '/visible',
|
||||||
*
|
op: 'replace',
|
||||||
* @param researcherProfile the profile to update
|
value: visible
|
||||||
* @param visible the visibility value to set
|
};
|
||||||
*/
|
|
||||||
setVisibility(researcherProfile: ResearcherProfile, visible: boolean): Observable<ResearcherProfile> {
|
|
||||||
|
|
||||||
const replaceOperation: ReplaceOperation<boolean> = {
|
return this.patch(researcherProfile, [replaceOperation]).pipe (
|
||||||
path: '/visible',
|
switchMap( ( ) => this.findById(researcherProfile.id))
|
||||||
op: 'replace',
|
);
|
||||||
value: visible
|
}
|
||||||
};
|
|
||||||
|
|
||||||
return this.patch(researcherProfile, [replaceOperation]).pipe (
|
patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable<RemoteData<ResearcherProfile>> {
|
||||||
switchMap( ( ) => this.findById(researcherProfile.id))
|
return this.dataService.patch(researcherProfile, operations);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
patch(researcherProfile: ResearcherProfile, operations: Operation[]): Observable<RemoteData<ResearcherProfile>> {
|
/**
|
||||||
return this.dataService.patch(researcherProfile, operations);
|
* Check if the given item is linked to an ORCID profile.
|
||||||
}
|
*
|
||||||
|
* @param item the item to check
|
||||||
|
* @returns the check result
|
||||||
|
*/
|
||||||
|
isLinkedToOrcid(item: Item): boolean {
|
||||||
|
return item.hasMetadata('cris.orcid.authenticated');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if only the admin users can disconnect a researcher profile from ORCID.
|
||||||
|
*
|
||||||
|
* @returns the check result
|
||||||
|
*/
|
||||||
|
onlyAdminCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||||
|
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||||
|
map((property) => property.values.map( (value) => value.toLowerCase()).includes('only_admin'))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the profile's owner can disconnect that profile from ORCID.
|
||||||
|
*
|
||||||
|
* @returns the check result
|
||||||
|
*/
|
||||||
|
ownerCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||||
|
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||||
|
map((property) => {
|
||||||
|
const values = property.values.map( (value) => value.toLowerCase());
|
||||||
|
return values.includes('only_owner') || values.includes('admin_and_owner');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the admin users can disconnect a researcher profile from ORCID.
|
||||||
|
*
|
||||||
|
* @returns the check result
|
||||||
|
*/
|
||||||
|
adminCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||||
|
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||||
|
map((property) => {
|
||||||
|
const values = property.values.map( (value) => value.toLowerCase());
|
||||||
|
return values.includes('only_admin') || values.includes('admin_and_owner');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the given item represents a profile unlink it from ORCID.
|
||||||
|
*/
|
||||||
|
unlinkOrcid(item: Item): Observable<RemoteData<ResearcherProfile>> {
|
||||||
|
|
||||||
|
const operations: RemoveOperation[] = [{
|
||||||
|
path:'/orcid',
|
||||||
|
op:'remove'
|
||||||
|
}];
|
||||||
|
|
||||||
|
return this.findById(item.firstMetadata('cris.owner').authority).pipe(
|
||||||
|
switchMap((profile) => this.patch(profile, operations)),
|
||||||
|
getFinishedRemoteData()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
getOrcidAuthorizeUrl(profile: Item): Observable<string> {
|
||||||
|
return combineLatest([
|
||||||
|
this.configurationService.findByPropertyName('orcid.authorize-url').pipe(getFirstSucceededRemoteDataPayload()),
|
||||||
|
this.configurationService.findByPropertyName('orcid.application-client-id').pipe(getFirstSucceededRemoteDataPayload()),
|
||||||
|
this.configurationService.findByPropertyName('orcid.scope').pipe(getFirstSucceededRemoteDataPayload())]
|
||||||
|
).pipe(
|
||||||
|
map(([authorizeUrl, clientId, scopes]) => {
|
||||||
|
const redirectUri = environment.rest.baseUrl + '/api/cris/orcid/' + profile.id + '/?url=' + encodeURIComponent(this.router.url);
|
||||||
|
return authorizeUrl.values[0] + '?client_id=' + clientId.values[0] + '&redirect_uri=' + redirectUri + '&response_type=code&scope='
|
||||||
|
+ scopes.values.join(' ');
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a researcher profile starting from an external source URI
|
* Creates a researcher profile starting from an external source URI
|
||||||
@@ -180,4 +258,10 @@ export class ResearcherProfileService {
|
|||||||
return this.rdbService.buildFromRequestUUID(requestId);
|
return this.rdbService.buildFromRequestUUID(requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getOrcidDisconnectionAllowedUsersConfiguration(): Observable<ConfigurationProperty> {
|
||||||
|
return this.configurationService.findByPropertyName('orcid.disconnection.allowed-users').pipe(
|
||||||
|
getFirstSucceededRemoteDataPayload()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,7 @@ import { ThemedFileSectionComponent } from './simple/field-components/file-secti
|
|||||||
import { OrcidAuthComponent } from './orcid-page/orcid-auth/orcid-auth.component';
|
import { OrcidAuthComponent } from './orcid-page/orcid-auth/orcid-auth.component';
|
||||||
import { OrcidPageComponent } from './orcid-page/orcid-page.component';
|
import { OrcidPageComponent } from './orcid-page/orcid-page.component';
|
||||||
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
|
||||||
|
import { OrcidSettingComponent } from './orcid-page/orcid-sync/orcid-setting.component';
|
||||||
|
|
||||||
|
|
||||||
const ENTRY_COMPONENTS = [
|
const ENTRY_COMPONENTS = [
|
||||||
@@ -71,7 +72,8 @@ const DECLARATIONS = [
|
|||||||
MiradorViewerComponent,
|
MiradorViewerComponent,
|
||||||
VersionPageComponent,
|
VersionPageComponent,
|
||||||
OrcidPageComponent,
|
OrcidPageComponent,
|
||||||
OrcidAuthComponent
|
OrcidAuthComponent,
|
||||||
|
OrcidSettingComponent
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@@ -1 +1,2 @@
|
|||||||
<ds-orcid-auth></ds-orcid-auth>
|
<ds-orcid-auth></ds-orcid-auth>
|
||||||
|
<ds-orcid-setting></ds-orcid-setting>
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
<div class="container custom-accordion mb-4">
|
||||||
|
<ngb-accordion activeIds="setting">
|
||||||
|
<ngb-panel title="{{'person.orcid.sync.setting' | translate}}" id="setting">
|
||||||
|
<ng-template ngbPanelContent>
|
||||||
|
<div class="container">
|
||||||
|
<form #f="ngForm" (ngSubmit)="onSubmit(f.form)">
|
||||||
|
<div class="row alert alert-info">
|
||||||
|
{{ 'person.page.orcid.synchronization-mode-message' | translate}}
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="card m-2 p-0 col-md">
|
||||||
|
<div class="card-header">{{ 'person.page.orcid.synchronization-mode'| translate }}</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="syncMode">{{ 'person.page.orcid.synchronization-mode.label'| translate }}</label>
|
||||||
|
<select class="form-control" [(ngModel)]="currentSyncMode" name="syncMode" id="syncMode" required>
|
||||||
|
<option *ngFor="let syncMode of syncModes" [value]="syncMode.value">{{ syncMode.label | translate }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="card m-2 col-md p-0">
|
||||||
|
<div class="card-header">{{ 'person.page.orcid.publications-preferences'| translate }}</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="m-3">
|
||||||
|
<div class="form-group" >
|
||||||
|
<div *ngFor="let option of syncPublicationOptions" class="row form-check">
|
||||||
|
<input type="radio" [(ngModel)]="currentSyncPublications"
|
||||||
|
name="syncPublications" id="publicationOption_{{option.value}}" [value]="option.value" required >
|
||||||
|
<label for="publicationOption_{{option.value}}" class="ml-2">{{option.label | translate}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card m-2 col-md p-0">
|
||||||
|
<div class="card-header">{{ 'person.page.orcid.funding-preferences'| translate }}</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="m-3">
|
||||||
|
<div class="form-group" >
|
||||||
|
<div *ngFor="let option of syncFundingOptions" class="row form-check">
|
||||||
|
<input type="radio" [(ngModel)]="currentSyncFundings"
|
||||||
|
name="syncFundings" id="fundingOption_{{option.value}}" [value]="option.value" required >
|
||||||
|
<label for="fundingOption_{{option.value}}" class="ml-2">{{option.label | translate}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card m-2 col-md p-0">
|
||||||
|
<div class="card-header">{{ 'person.page.orcid.profile-preferences'| translate }}</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="m-3">
|
||||||
|
<div class="form-group" >
|
||||||
|
<div *ngFor="let option of syncProfileOptions" class="row form-check">
|
||||||
|
<input type="checkbox" [(ngModel)]="option.checked"
|
||||||
|
name="syncProfile_{{option.value}}" id="profileOption_{{option.value}}" [value]="option.value" >
|
||||||
|
<label for="profileOption_{{option.value}}" class="ml-2">{{option.label | translate}}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<button type="submit" class="btn btn-primary float-right m-2">
|
||||||
|
<i class="fas fa-edit"></i>
|
||||||
|
{{ 'person.page.orcid.save.preference.changes' | translate }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</ngb-panel>
|
||||||
|
</ngb-accordion>
|
||||||
|
</div>
|
@@ -0,0 +1,139 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { FormGroup } from '@angular/forms';
|
||||||
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { Operation } from 'fast-json-patch';
|
||||||
|
import { switchMap } from 'rxjs/operators';
|
||||||
|
import { AuthService } from '../../../core/auth/auth.service';
|
||||||
|
import { ItemDataService } from '../../../core/data/item-data.service';
|
||||||
|
import { RemoteData } from '../../../core/data/remote-data';
|
||||||
|
import { ResearcherProfileService } from '../../../core/profile/researcher-profile.service';
|
||||||
|
import { Item } from '../../../core/shared/item.model';
|
||||||
|
import { getFinishedRemoteData, getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||||
|
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-orcid-setting',
|
||||||
|
templateUrl: './orcid-setting.component.html',
|
||||||
|
styleUrls: ['./orcid-setting.component.scss']
|
||||||
|
})
|
||||||
|
export class OrcidSettingComponent implements OnInit {
|
||||||
|
|
||||||
|
messagePrefix = 'person.page.orcid';
|
||||||
|
|
||||||
|
currentSyncMode: string;
|
||||||
|
|
||||||
|
currentSyncPublications: string;
|
||||||
|
|
||||||
|
currentSyncFundings: string;
|
||||||
|
|
||||||
|
syncModes: { value: string, label: string }[];
|
||||||
|
|
||||||
|
syncPublicationOptions: { value: string, label: string }[];
|
||||||
|
|
||||||
|
syncFundingOptions: {value: string, label: string}[];
|
||||||
|
|
||||||
|
syncProfileOptions: { value: string, label: string, checked: boolean }[];
|
||||||
|
|
||||||
|
item: Item;
|
||||||
|
|
||||||
|
constructor(private researcherProfileService: ResearcherProfileService,
|
||||||
|
protected translateService: TranslateService,
|
||||||
|
private notificationsService: NotificationsService,
|
||||||
|
public authService: AuthService,
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private itemService: ItemDataService
|
||||||
|
) {
|
||||||
|
this.itemService.findById(this.route.snapshot.paramMap.get('id'), true, true).pipe(getFirstCompletedRemoteData()).subscribe((data: RemoteData<Item>) => {
|
||||||
|
this.item = data.payload;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.syncModes = [
|
||||||
|
{
|
||||||
|
label: this.messagePrefix + '.synchronization-mode.batch',
|
||||||
|
value: 'BATCH'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: this.messagePrefix + '.synchronization-mode.manual',
|
||||||
|
value: 'MANUAL'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
this.syncPublicationOptions = ['DISABLED', 'ALL']
|
||||||
|
.map((value) => {
|
||||||
|
return {
|
||||||
|
label: this.messagePrefix + '.sync-publications.' + value.toLowerCase(),
|
||||||
|
value: value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.syncFundingOptions = ['DISABLED', 'ALL']
|
||||||
|
.map((value) => {
|
||||||
|
return {
|
||||||
|
label: this.messagePrefix + '.sync-fundings.' + value.toLowerCase(),
|
||||||
|
value: value,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const syncProfilePreferences = this.item.allMetadataValues('cris.orcid.sync-profile');
|
||||||
|
|
||||||
|
this.syncProfileOptions = ['AFFILIATION', 'EDUCATION', 'BIOGRAPHICAL', 'IDENTIFIERS']
|
||||||
|
.map((value) => {
|
||||||
|
return {
|
||||||
|
label: this.messagePrefix + '.sync-profile.' + value.toLowerCase(),
|
||||||
|
value: value,
|
||||||
|
checked: syncProfilePreferences.includes(value)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.currentSyncMode = this.getCurrentPreference('cris.orcid.sync-mode', ['BATCH, MANUAL'], 'MANUAL');
|
||||||
|
this.currentSyncPublications = this.getCurrentPreference('cris.orcid.sync-publications', ['DISABLED', 'ALL'], 'DISABLED');
|
||||||
|
this.currentSyncFundings = this.getCurrentPreference('cris.orcid.sync-fundings', ['DISABLED', 'ALL'], 'DISABLED');
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit(form: FormGroup) {
|
||||||
|
const operations: Operation[] = [];
|
||||||
|
this.fillOperationsFor(operations, '/orcid/mode', form.value.syncMode);
|
||||||
|
this.fillOperationsFor(operations, '/orcid/publications', form.value.syncPublications);
|
||||||
|
this.fillOperationsFor(operations, '/orcid/fundings', form.value.syncFundings);
|
||||||
|
|
||||||
|
const syncProfileValue = this.syncProfileOptions
|
||||||
|
.map((syncProfileOption => syncProfileOption.value))
|
||||||
|
.filter((value) => form.value['syncProfile_' + value])
|
||||||
|
.join(',');
|
||||||
|
|
||||||
|
this.fillOperationsFor(operations, '/orcid/profile', syncProfileValue);
|
||||||
|
|
||||||
|
if (operations.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.researcherProfileService.findById(this.item.firstMetadata('cris.owner').authority).pipe(
|
||||||
|
switchMap((profile) => this.researcherProfileService.patch(profile, operations)),
|
||||||
|
getFinishedRemoteData()
|
||||||
|
).subscribe((remoteData) => {
|
||||||
|
if (remoteData.isSuccess) {
|
||||||
|
this.notificationsService.success(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.success'));
|
||||||
|
} else {
|
||||||
|
this.notificationsService.error(this.translateService.get(this.messagePrefix + '.synchronization-settings-update.error'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fillOperationsFor(operations: Operation[], path: string, currentValue: string) {
|
||||||
|
operations.push({
|
||||||
|
path: path,
|
||||||
|
op: 'replace',
|
||||||
|
value: currentValue
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentPreference(metadataField: string, allowedValues: string[], defaultValue: string): string {
|
||||||
|
const currentPreference = this.item.firstMetadataValue(metadataField);
|
||||||
|
return (currentPreference && allowedValues.includes(currentPreference)) ? currentPreference : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@@ -7,7 +7,6 @@ import { renderAuthMethodFor } from '../log-in.methods-decorator';
|
|||||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||||
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||||
|
|
||||||
import { CoreState } from '../../../../core/core.reducers';
|
|
||||||
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
|
import { isAuthenticated, isAuthenticationLoading } from '../../../../core/auth/selectors';
|
||||||
import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../../../../core/services/window.service';
|
||||||
import { isNotNull, isEmpty } from '../../../empty.util';
|
import { isNotNull, isEmpty } from '../../../empty.util';
|
||||||
@@ -15,6 +14,7 @@ import { AuthService } from '../../../../core/auth/auth.service';
|
|||||||
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
||||||
import { take } from 'rxjs/operators';
|
import { take } from 'rxjs/operators';
|
||||||
import { URLCombiner } from '../../../../core/url-combiner/url-combiner';
|
import { URLCombiner } from '../../../../core/url-combiner/url-combiner';
|
||||||
|
import {CoreState} from "../../../../core/core-state.model";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-log-in-orcid',
|
selector: 'ds-log-in-orcid',
|
||||||
|
Reference in New Issue
Block a user