33 Component ,
44 EventEmitter ,
55 Input ,
6+ OnDestroy ,
67 OnInit ,
78 Output ,
89} from '@angular/core' ;
@@ -15,17 +16,32 @@ import {
1516 TranslateService ,
1617} from '@ngx-translate/core' ;
1718import { Operation } from 'fast-json-patch' ;
18- import { of } from 'rxjs' ;
19- import { switchMap } from 'rxjs/operators' ;
19+ import {
20+ BehaviorSubject ,
21+ Observable ,
22+ } from 'rxjs' ;
23+ import {
24+ catchError ,
25+ filter ,
26+ map ,
27+ switchMap ,
28+ take ,
29+ takeUntil ,
30+ } from 'rxjs/operators' ;
2031
2132import { RemoteData } from '../../../core/data/remote-data' ;
2233import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model' ;
2334import { ResearcherProfileDataService } from '../../../core/profile/researcher-profile-data.service' ;
2435import { Item } from '../../../core/shared/item.model' ;
25- import { getFirstCompletedRemoteData } from '../../../core/shared/operators' ;
36+ import {
37+ getFirstCompletedRemoteData ,
38+ getRemoteDataPayload ,
39+ } from '../../../core/shared/operators' ;
2640import { AlertComponent } from '../../../shared/alert/alert.component' ;
2741import { AlertType } from '../../../shared/alert/alert-type' ;
42+ import { hasValue } from '../../../shared/empty.util' ;
2843import { NotificationsService } from '../../../shared/notifications/notifications.service' ;
44+ import { createFailedRemoteDataObjectFromError$ } from '../../../shared/remote-data.utils' ;
2945
3046@Component ( {
3147 selector : 'ds-orcid-sync-setting' ,
@@ -39,14 +55,9 @@ import { NotificationsService } from '../../../shared/notifications/notification
3955 ] ,
4056 standalone : true ,
4157} )
42- export class OrcidSyncSettingsComponent implements OnInit {
58+ export class OrcidSyncSettingsComponent implements OnInit , OnDestroy {
4359 protected readonly AlertType = AlertType ;
4460
45- /**
46- * The item for which showing the orcid settings
47- */
48- @Input ( ) item : Item ;
49-
5061 /**
5162 * The prefix used for i18n keys
5263 */
@@ -91,12 +102,39 @@ export class OrcidSyncSettingsComponent implements OnInit {
91102 * An event emitted when settings are updated
92103 */
93104 @Output ( ) settingsUpdated : EventEmitter < void > = new EventEmitter < void > ( ) ;
105+ /**
106+ * Emitter that triggers onDestroy lifecycle
107+ * @private
108+ */
109+ readonly #destroy$ = new EventEmitter < void > ( ) ;
110+ /**
111+ * {@link BehaviorSubject } that reflects {@link item } input changes
112+ * @private
113+ */
114+ readonly #item$ = new BehaviorSubject < Item > ( null ) ;
115+ /**
116+ * {@link Observable } that contains {@link ResearcherProfile } linked to the {@link #item$ }
117+ * @private
118+ */
119+ #researcherProfile$: Observable < ResearcherProfile > ;
94120
95121 constructor ( private researcherProfileService : ResearcherProfileDataService ,
96122 private notificationsService : NotificationsService ,
97123 private translateService : TranslateService ) {
98124 }
99125
126+ /**
127+ * The item for which showing the orcid settings
128+ */
129+ @Input ( )
130+ set item ( item : Item ) {
131+ this . #item$. next ( item ) ;
132+ }
133+
134+ ngOnDestroy ( ) : void {
135+ this . #destroy$. next ( ) ;
136+ }
137+
100138 /**
101139 * Init orcid settings form
102140 */
@@ -128,20 +166,21 @@ export class OrcidSyncSettingsComponent implements OnInit {
128166 } ;
129167 } ) ;
130168
131- const syncProfilePreferences = this . item . allMetadataValues ( 'dspace.orcid.sync-profile' ) ;
169+ this . updateSyncProfileOptions ( this . #item$. asObservable ( ) ) ;
170+ this . updateSyncPreferences ( this . #item$. asObservable ( ) ) ;
132171
133- this . syncProfileOptions = [ 'BIOGRAPHICAL' , 'IDENTIFIERS' ]
134- . map ( ( value ) => {
135- return {
136- label : this . messagePrefix + '.sync-profile.' + value . toLowerCase ( ) ,
137- value : value ,
138- checked : syncProfilePreferences . includes ( value ) ,
139- } ;
140- } ) ;
141-
142- this . currentSyncMode = this . getCurrentPreference ( 'dspace.orcid.sync-mode' , [ 'BATCH' , 'MANUAL' ] , 'MANUAL' ) ;
143- this . currentSyncPublications = this . getCurrentPreference ( 'dspace.orcid.sync-publications' , [ 'DISABLED' , 'ALL' ] , 'DISABLED' ) ;
144- this . currentSyncFunding = this . getCurrentPreference ( 'dspace.orcid.sync-fundings' , [ 'DISABLED' , 'ALL' ] , 'DISABLED' ) ;
172+ this . #researcherProfile$ =
173+ this . #item$ . pipe (
174+ switchMap ( item =>
175+ this . researcherProfileService . findByRelatedItem ( item )
176+ . pipe (
177+ getFirstCompletedRemoteData ( ) ,
178+ catchError ( createFailedRemoteDataObjectFromError$ < ResearcherProfile > ) ,
179+ getRemoteDataPayload ( ) ,
180+ ) ,
181+ ) ,
182+ takeUntil ( this . #destroy$ ) ,
183+ ) ;
145184 }
146185
147186 /**
@@ -166,37 +205,84 @@ export class OrcidSyncSettingsComponent implements OnInit {
166205 return ;
167206 }
168207
169- this . researcherProfileService . findByRelatedItem ( this . item ) . pipe (
170- getFirstCompletedRemoteData ( ) ,
171- switchMap ( ( profileRD : RemoteData < ResearcherProfile > ) => {
172- if ( profileRD . hasSucceeded ) {
173- return this . researcherProfileService . patch ( profileRD . payload , operations ) . pipe (
174- getFirstCompletedRemoteData ( ) ,
175- ) ;
208+ this . #researcherProfile$
209+ . pipe (
210+ switchMap ( researcherProfile => this . researcherProfileService . patch ( researcherProfile , operations ) ) ,
211+ getFirstCompletedRemoteData ( ) ,
212+ catchError ( createFailedRemoteDataObjectFromError$ < ResearcherProfile > ) ,
213+ take ( 1 ) ,
214+ )
215+ . subscribe ( ( remoteData : RemoteData < ResearcherProfile > ) => {
216+ if ( remoteData . hasFailed ) {
217+ this . notificationsService . error ( this . translateService . get ( this . messagePrefix + '.synchronization-settings-update.error' ) ) ;
176218 } else {
177- return of ( profileRD ) ;
219+ this . notificationsService . success ( this . translateService . get ( this . messagePrefix + '.synchronization-settings-update.success' ) ) ;
220+ this . settingsUpdated . emit ( ) ;
178221 }
179- } ) ,
180- ) . subscribe ( ( remoteData : RemoteData < ResearcherProfile > ) => {
181- if ( remoteData . isSuccess ) {
182- this . notificationsService . success ( this . translateService . get ( this . messagePrefix + '.synchronization-settings-update.success' ) ) ;
183- this . settingsUpdated . emit ( ) ;
184- } else {
185- this . notificationsService . error ( this . translateService . get ( this . messagePrefix + '.synchronization-settings-update.error' ) ) ;
186- }
187- } ) ;
222+ } ) ;
223+ }
224+
225+ /**
226+ *
227+ * Handles subscriptions to populate sync preferences
228+ *
229+ * @param item observable that emits update on item changes
230+ * @private
231+ */
232+ private updateSyncPreferences ( item : Observable < Item > ) {
233+ item . pipe (
234+ filter ( hasValue ) ,
235+ map ( i => this . getCurrentPreference ( i , 'dspace.orcid.sync-mode' , [ 'BATCH' , 'MANUAL' ] , 'MANUAL' ) ) ,
236+ takeUntil ( this . #destroy$) ,
237+ ) . subscribe ( val => this . currentSyncMode = val ) ;
238+ item . pipe (
239+ filter ( hasValue ) ,
240+ map ( i => this . getCurrentPreference ( i , 'dspace.orcid.sync-publications' , [ 'DISABLED' , 'ALL' ] , 'DISABLED' ) ) ,
241+ takeUntil ( this . #destroy$) ,
242+ ) . subscribe ( val => this . currentSyncPublications = val ) ;
243+ item . pipe (
244+ filter ( hasValue ) ,
245+ map ( i => this . getCurrentPreference ( i , 'dspace.orcid.sync-fundings' , [ 'DISABLED' , 'ALL' ] , 'DISABLED' ) ) ,
246+ takeUntil ( this . #destroy$) ,
247+ ) . subscribe ( val => this . currentSyncFunding = val ) ;
248+ }
249+
250+ /**
251+ * Handles subscription to populate the {@link syncProfileOptions} field
252+ *
253+ * @param item observable that emits update on item changes
254+ * @private
255+ */
256+ private updateSyncProfileOptions ( item : Observable < Item > ) {
257+ item . pipe (
258+ filter ( hasValue ) ,
259+ map ( i => i . allMetadataValues ( 'dspace.orcid.sync-profile' ) ) ,
260+ map ( metadata =>
261+ [ 'BIOGRAPHICAL' , 'IDENTIFIERS' ]
262+ . map ( ( value ) => {
263+ return {
264+ label : this . messagePrefix + '.sync-profile.' + value . toLowerCase ( ) ,
265+ value : value ,
266+ checked : metadata . includes ( value ) ,
267+ } ;
268+ } ) ,
269+ ) ,
270+ takeUntil ( this . #destroy$) ,
271+ )
272+ . subscribe ( value => this . syncProfileOptions = value ) ;
188273 }
189274
190275 /**
191276 * Retrieve setting saved in the item's metadata
192277 *
278+ * @param item The item from which retrieve settings
193279 * @param metadataField The metadata name that contains setting
194280 * @param allowedValues The allowed values
195281 * @param defaultValue The default value
196282 * @private
197283 */
198- private getCurrentPreference ( metadataField : string , allowedValues : string [ ] , defaultValue : string ) : string {
199- const currentPreference = this . item . firstMetadataValue ( metadataField ) ;
284+ private getCurrentPreference ( item : Item , metadataField : string , allowedValues : string [ ] , defaultValue : string ) : string {
285+ const currentPreference = item . firstMetadataValue ( metadataField ) ;
200286 return ( currentPreference && allowedValues . includes ( currentPreference ) ) ? currentPreference : defaultValue ;
201287 }
202288
@@ -216,3 +302,4 @@ export class OrcidSyncSettingsComponent implements OnInit {
216302 }
217303
218304}
305+
0 commit comments