11import { Injectable } from '@angular/core' ;
2- import { Observable } from 'rxjs' ;
3- import { map , switchMap , mergeMap } from 'rxjs/operators' ;
2+ import { Observable , of } from 'rxjs' ;
3+ import { map , switchMap , mergeMap , catchError } from 'rxjs/operators' ;
44import { FollowLinkConfig , followLink } from '../../../shared/utils/follow-link-config.model' ;
55import { RequestService } from '../../data/request.service' ;
66import { RemoteData } from '../../data/remote-data' ;
77import { PaginatedList } from '../../data/paginated-list.model' ;
88import { Vocabulary } from './models/vocabulary.model' ;
99import { VocabularyEntry } from './models/vocabulary-entry.model' ;
1010import { isNotEmpty } from '../../../shared/empty.util' ;
11+ import { ExternalSourceDataService } from '../../data/external-source-data.service' ;
12+ import { ExternalSourceEntry } from '../../shared/external-source-entry.model' ;
13+ import { PaginatedSearchOptions } from '../../../shared/search/models/paginated-search-options.model' ;
14+ import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model' ;
1115import {
1216 getFirstSucceededRemoteDataPayload ,
1317 getFirstSucceededRemoteListPayload ,
@@ -20,6 +24,8 @@ import { PageInfo } from '../../shared/page-info.model';
2024import { FindListOptions } from '../../data/find-list-options.model' ;
2125import { VocabularyEntryDetailsDataService } from './vocabulary-entry-details.data.service' ;
2226import { VocabularyDataService } from './vocabulary.data.service' ;
27+ import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils' ;
28+ import { buildPaginatedList } from '../../data/paginated-list.model' ;
2329
2430/**
2531 * A service responsible for fetching/sending data from/to the REST API on the vocabularies endpoint
@@ -32,6 +38,7 @@ export class VocabularyService {
3238 protected requestService : RequestService ,
3339 protected vocabularyDataService : VocabularyDataService ,
3440 protected vocabularyEntryDetailDataService : VocabularyEntryDetailsDataService ,
41+ protected externalSourceDataService : ExternalSourceDataService ,
3542 ) {
3643 }
3744
@@ -124,6 +131,61 @@ export class VocabularyService {
124131 * Return an observable that emits object list
125132 */
126133 getVocabularyEntriesByValue ( value : string , exact : boolean , vocabularyOptions : VocabularyOptions , pageInfo : PageInfo ) : Observable < RemoteData < PaginatedList < VocabularyEntry > > > {
134+ // Handle authority fields specially for DSpace 7 compatibility
135+ const authorityFields = [ 'dc.contributor.author' , 'dc.creator' , 'dc.contributor.editor' , 'dc.contributor.advisor' ] ;
136+ if ( authorityFields . includes ( vocabularyOptions . name ) ) {
137+ // For authority fields, use ORCID external source if there's search text
138+ if ( value && value . length >= 2 ) {
139+ // Create search options for ORCID
140+ const paginationOptions = Object . assign ( new PaginationComponentOptions ( ) , {
141+ id : 'orcid-search' ,
142+ currentPage : pageInfo . currentPage || 1 ,
143+ pageSize : pageInfo . elementsPerPage || 10
144+ } ) ;
145+
146+ const searchOptions = new PaginatedSearchOptions ( {
147+ query : value ,
148+ pagination : paginationOptions
149+ } ) ;
150+
151+ // Use ORCID external source (try both orcid and orcidV2)
152+ return this . externalSourceDataService . getExternalSourceEntries ( 'orcid' , searchOptions ) . pipe (
153+ switchMap ( ( orcidResponse : RemoteData < PaginatedList < ExternalSourceEntry > > ) => {
154+ if ( orcidResponse . hasSucceeded && orcidResponse . payload && orcidResponse . payload . page . length > 0 ) {
155+ // Convert ExternalSourceEntry to VocabularyEntry
156+ const vocabularyEntries : VocabularyEntry [ ] = orcidResponse . payload . page . map ( entry => {
157+ const vocabEntry = new VocabularyEntry ( ) ;
158+ // Display shows author name + ORCID for selection
159+ vocabEntry . display = `${ entry . display } (ORCID: ${ entry . id } )` ;
160+ // Value should be just the author name (what goes in the main field)
161+ vocabEntry . value = entry . display ;
162+ // Authority is the ORCID ID (what goes in the authority field)
163+ vocabEntry . authority = entry . id ;
164+ vocabEntry . otherInformation = { orcid : entry . id } ;
165+ return vocabEntry ;
166+ } ) ;
167+
168+ const resultList = buildPaginatedList ( pageInfo , vocabularyEntries ) ;
169+ return createSuccessfulRemoteDataObject$ ( resultList ) ;
170+ } else {
171+ // Return empty list if no results
172+ const emptyList = buildPaginatedList ( new PageInfo ( ) , [ ] ) ;
173+ return createSuccessfulRemoteDataObject$ ( emptyList ) ;
174+ }
175+ } ) ,
176+ catchError ( ( ) => {
177+ // On error, return empty list
178+ const emptyList = buildPaginatedList ( new PageInfo ( ) , [ ] ) ;
179+ return createSuccessfulRemoteDataObject$ ( emptyList ) ;
180+ } )
181+ ) ;
182+ } else {
183+ // Return empty list if no search text
184+ const emptyList = buildPaginatedList ( new PageInfo ( ) , [ ] ) ;
185+ return createSuccessfulRemoteDataObject$ ( emptyList ) ;
186+ }
187+ }
188+
127189 const options : VocabularyFindOptions = new VocabularyFindOptions (
128190 null ,
129191 value ,
0 commit comments