1- import { Component , EventEmitter , Input , OnInit , Output } from '@angular/core' ;
1+ import { ChangeDetectorRef , Component , EventEmitter , Input , OnChanges , OnInit , Output , SimpleChanges } from '@angular/core' ;
22import { DsoEditMetadataChangeType , DsoEditMetadataValue } from '../dso-edit-metadata-form' ;
33import { Observable } from 'rxjs/internal/Observable' ;
44import {
88import { RelationshipDataService } from '../../../core/data/relationship-data.service' ;
99import { DSpaceObject } from '../../../core/shared/dspace-object.model' ;
1010import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model' ;
11- import { map , switchMap } from 'rxjs/operators' ;
11+ import { map , switchMap , take } from 'rxjs/operators' ;
1212import { getItemPageRoute } from '../../../item-page/item-page-routing-paths' ;
1313import { DSONameService } from '../../../core/breadcrumbs/dso-name.service' ;
1414import { EMPTY } from 'rxjs/internal/observable/empty' ;
@@ -17,7 +17,7 @@ import { Vocabulary } from '../../../core/submission/vocabularies/models/vocabul
1717import { UntypedFormControl , UntypedFormGroup } from '@angular/forms' ;
1818import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model' ;
1919import { ConfidenceType } from '../../../core/shared/confidence-type' ;
20- import { getFirstSucceededRemoteData , getFirstSucceededRemoteDataPayload , getRemoteDataPayload } from '../../../core/shared/operators' ;
20+ import { getFirstCompletedRemoteData , getFirstSucceededRemoteData , getFirstSucceededRemoteDataPayload , getRemoteDataPayload , metadataFieldsToString } from '../../../core/shared/operators' ;
2121import { DsDynamicOneboxModelConfig , DynamicOneboxModel } from '../../../shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.model' ;
2222import { DynamicScrollableDropdownModel , DynamicScrollableDropdownModelConfig } from '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model' ;
2323import { ItemDataService } from '../../../core/data/item-data.service' ;
@@ -27,6 +27,9 @@ import { Collection } from '../../../core/shared/collection.model';
2727import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model' ;
2828import { isNotEmpty } from '../../../shared/empty.util' ;
2929import { of as observableOf } from 'rxjs' ;
30+ import { RegistryService } from 'src/app/core/registry/registry.service' ;
31+ import { TranslateService } from '@ngx-translate/core' ;
32+ import { NotificationsService } from 'src/app/shared/notifications/notifications.service' ;
3033
3134@Component ( {
3235 selector : 'ds-dso-edit-metadata-value' ,
@@ -36,7 +39,7 @@ import { of as observableOf } from 'rxjs';
3639/**
3740 * Component displaying a single editable row for a metadata value
3841 */
39- export class DsoEditMetadataValueComponent implements OnInit {
42+ export class DsoEditMetadataValueComponent implements OnInit , OnChanges {
4043 /**
4144 * The parent {@link DSpaceObject} to display a metadata form for
4245 * Also used to determine metadata-representations in case of virtual metadata
@@ -155,7 +158,11 @@ export class DsoEditMetadataValueComponent implements OnInit {
155158 constructor ( protected relationshipService : RelationshipDataService ,
156159 protected dsoNameService : DSONameService ,
157160 protected vocabularyService : VocabularyService ,
158- protected itemService : ItemDataService ) {
161+ protected itemService : ItemDataService ,
162+ protected cdr : ChangeDetectorRef ,
163+ protected registryService : RegistryService ,
164+ protected notificationsService : NotificationsService ,
165+ protected translate : TranslateService ) {
159166 }
160167
161168 ngOnInit ( ) : void {
@@ -275,6 +282,56 @@ export class DsoEditMetadataValueComponent implements OnInit {
275282 } ) ) ;
276283 }
277284
285+ /**
286+ * Change callback for the component. Check if the mdField has changed to retrieve whether it is metadata
287+ * that uses a controlled vocabulary and update the related properties
288+ *
289+ * @param {SimpleChanges } changes
290+ */
291+ ngOnChanges ( changes : SimpleChanges ) : void {
292+ if ( isNotEmpty ( changes . mdField ) && ! changes . mdField . firstChange ) {
293+ if ( isNotEmpty ( changes . mdField . currentValue ) ) {
294+ if ( isNotEmpty ( changes . mdField . previousValue ) &&
295+ changes . mdField . previousValue !== changes . mdField . currentValue ) {
296+ // Clear authority value in case it has been assigned with the previous metadataField used
297+ this . mdValue . newValue . authority = null ;
298+ this . mdValue . newValue . confidence = ConfidenceType . CF_UNSET ;
299+ }
300+
301+ // Only ask if the current mdField have a period character to reduce request
302+ if ( changes . mdField . currentValue . includes ( '.' ) ) {
303+ this . validateMetadataField ( ) . subscribe ( ( isValid : boolean ) => {
304+ if ( isValid ) {
305+ this . initAuthorityProperties ( ) ;
306+ this . cdr . detectChanges ( ) ;
307+ }
308+ } ) ;
309+ }
310+ }
311+ }
312+ }
313+
314+ /**
315+ * Validate the metadata field to check if it exists on the server and return an observable boolean for success/error
316+ */
317+ validateMetadataField ( ) : Observable < boolean > {
318+ return this . registryService . queryMetadataFields ( this . mdField , null , true , false , followLink ( 'schema' ) ) . pipe (
319+ getFirstCompletedRemoteData ( ) ,
320+ switchMap ( ( rd ) => {
321+ if ( rd . hasSucceeded ) {
322+ return observableOf ( rd ) . pipe (
323+ metadataFieldsToString ( ) ,
324+ take ( 1 ) ,
325+ map ( ( fields : string [ ] ) => fields . indexOf ( this . mdField ) > - 1 )
326+ ) ;
327+ } else {
328+ this . notificationsService . error ( this . translate . instant ( `${ this . dsoType } .edit.metadata.metadatafield.error` ) , rd . errorMessage ) ;
329+ return [ false ] ;
330+ }
331+ } ) ,
332+ ) ;
333+ }
334+
278335 /**
279336 * Checks if this field use a authority vocabulary
280337 */
0 commit comments