From 07d30ff931b496999c6ff08fe51345276b2cf931 Mon Sep 17 00:00:00 2001 From: Toni Prieto Date: Mon, 1 Apr 2024 17:08:33 +0200 Subject: [PATCH] Create the model before displaying the vocabulary fields in edit item page --- .../dso-edit-metadata-value.component.html | 4 +- .../dso-edit-metadata-value.component.spec.ts | 34 ++---- .../dso-edit-metadata-value.component.ts | 114 ++++++++++-------- 3 files changed, 75 insertions(+), 77 deletions(-) diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html index b79b185b40d..03fd440acdb 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.html @@ -9,12 +9,12 @@
diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts index ccfcfca93c4..e89d2ee03a9 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.spec.ts @@ -10,10 +10,7 @@ import { import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; import { TranslateModule } from '@ngx-translate/core'; -import { - Observable, - of, -} from 'rxjs'; +import { of } from 'rxjs'; import { MetadataField } from 'src/app/core/metadata/metadata-field.model'; import { MetadataSchema } from 'src/app/core/metadata/metadata-schema.model'; import { RegistryService } from 'src/app/core/registry/registry.service'; @@ -346,14 +343,11 @@ describe('DsoEditMetadataValueComponent', () => { }); it('getModel should return a DynamicScrollableDropdownModel', () => { - const result = component.getModel(); + const model = component.getModel(); - expect(result instanceof Observable).toBe(true); + expect(model instanceof DynamicScrollableDropdownModel).toBe(true); + expect(model.vocabularyOptions.name).toBe(mockVocabularyScrollable.name); - result.subscribe((model) => { - expect(model instanceof DynamicScrollableDropdownModel).toBe(true); - expect(model.vocabularyOptions.name).toBe(mockVocabularyScrollable.name); - }); }); }); @@ -380,14 +374,10 @@ describe('DsoEditMetadataValueComponent', () => { }); it('getModel should return a DynamicOneboxModel', () => { - const result = component.getModel(); - - expect(result instanceof Observable).toBe(true); + const model = component.getModel(); - result.subscribe((model) => { - expect(model instanceof DynamicOneboxModel).toBe(true); - expect(model.vocabularyOptions.name).toBe(mockVocabularyHierarchical.name); - }); + expect(model instanceof DynamicOneboxModel).toBe(true); + expect(model.vocabularyOptions.name).toBe(mockVocabularyHierarchical.name); }); }); @@ -416,14 +406,10 @@ describe('DsoEditMetadataValueComponent', () => { }); it('getModel should return a DynamicOneboxModel', () => { - const result = component.getModel(); - - expect(result instanceof Observable).toBe(true); + const model = component.getModel(); - result.subscribe((model) => { - expect(model instanceof DynamicOneboxModel).toBe(true); - expect(model.vocabularyOptions.name).toBe(mockVocabularySuggester.name); - }); + expect(model instanceof DynamicOneboxModel).toBe(true); + expect(model.vocabularyOptions.name).toBe(mockVocabularySuggester.name); }); describe('authority key edition', () => { diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.ts b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.ts index 1aefe5af236..be17fd9d20a 100644 --- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.ts +++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata-value/dso-edit-metadata-value.component.ts @@ -29,6 +29,7 @@ import { TranslateService, } from '@ngx-translate/core'; import { + BehaviorSubject, EMPTY, Observable, of as observableOf, @@ -37,6 +38,7 @@ import { map, switchMap, take, + tap, } from 'rxjs/operators'; import { RegistryService } from 'src/app/core/registry/registry.service'; import { VocabularyService } from 'src/app/core/submission/vocabularies/vocabulary.service'; @@ -195,9 +197,9 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges { group = new UntypedFormGroup({ authorityField : new UntypedFormControl() }); /** - * Observable property of the model to use for editinf authorities values + * Model to use for editing authorities values */ - private model$: Observable; + private model$: BehaviorSubject = new BehaviorSubject(null); /** * Observable with information about the authority vocabulary used @@ -274,6 +276,8 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges { } this.isAuthorityControlled$ = this.vocabulary$.pipe( + // Create the model used by the authority fields to ensure its existence when the field is initialized + tap((v: Vocabulary) => this.model$.next(this.createModel(v))), map((result: Vocabulary) => isNotEmpty(result)), ); @@ -289,54 +293,62 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges { map((result: Vocabulary) => isNotEmpty(result) && !result.hierarchical && !result.scrollable), ); - this.model$ = this.vocabulary$.pipe( - map((vocabulary: Vocabulary) => { - let formFieldValue; - if (isNotEmpty(this.mdValue.newValue.value)) { - formFieldValue = new FormFieldMetadataValueObject(); - formFieldValue.value = this.mdValue.newValue.value; - formFieldValue.display = this.mdValue.newValue.value; - if (this.mdValue.newValue.authority) { - formFieldValue.authority = this.mdValue.newValue.authority; - formFieldValue.confidence = this.mdValue.newValue.confidence; - } - } else { - formFieldValue = this.mdValue.newValue.value; - } + } - const vocabularyOptions = vocabulary ? { - closed: false, - name: vocabulary.name, - } as VocabularyOptions : null; - - if (!vocabulary.scrollable) { - const model: DsDynamicOneboxModelConfig = { - id: 'authorityField', - label: `${this.dsoType}.edit.metadata.edit.value`, - vocabularyOptions: vocabularyOptions, - metadataFields: [this.mdField], - value: formFieldValue, - repeatable: false, - submissionId: 'edit-metadata', - hasSelectableMetadata: false, - }; - return new DynamicOneboxModel(model); - } else { - const model: DynamicScrollableDropdownModelConfig = { - id: 'authorityField', - label: `${this.dsoType}.edit.metadata.edit.value`, - placeholder: `${this.dsoType}.edit.metadata.edit.value`, - vocabularyOptions: vocabularyOptions, - metadataFields: [this.mdField], - value: formFieldValue, - repeatable: false, - submissionId: 'edit-metadata', - hasSelectableMetadata: false, - maxOptions: 10, - }; - return new DynamicScrollableDropdownModel(model); + /** + * Returns a {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model based on the + * vocabulary used. + */ + private createModel(vocabulary: Vocabulary): DynamicOneboxModel | DynamicScrollableDropdownModel { + if (isNotEmpty(vocabulary)) { + let formFieldValue; + if (isNotEmpty(this.mdValue.newValue.value)) { + formFieldValue = new FormFieldMetadataValueObject(); + formFieldValue.value = this.mdValue.newValue.value; + formFieldValue.display = this.mdValue.newValue.value; + if (this.mdValue.newValue.authority) { + formFieldValue.authority = this.mdValue.newValue.authority; + formFieldValue.confidence = this.mdValue.newValue.confidence; } - })); + } else { + formFieldValue = this.mdValue.newValue.value; + } + + const vocabularyOptions = vocabulary ? { + closed: false, + name: vocabulary.name, + } as VocabularyOptions : null; + + if (!vocabulary.scrollable) { + const model: DsDynamicOneboxModelConfig = { + id: 'authorityField', + label: `${this.dsoType}.edit.metadata.edit.value`, + vocabularyOptions: vocabularyOptions, + metadataFields: [this.mdField], + value: formFieldValue, + repeatable: false, + submissionId: 'edit-metadata', + hasSelectableMetadata: false, + }; + return new DynamicOneboxModel(model); + } else { + const model: DynamicScrollableDropdownModelConfig = { + id: 'authorityField', + label: `${this.dsoType}.edit.metadata.edit.value`, + placeholder: `${this.dsoType}.edit.metadata.edit.value`, + vocabularyOptions: vocabularyOptions, + metadataFields: [this.mdField], + value: formFieldValue, + repeatable: false, + submissionId: 'edit-metadata', + hasSelectableMetadata: false, + maxOptions: 10, + }; + return new DynamicScrollableDropdownModel(model); + } + } else { + return null; + } } /** @@ -434,11 +446,11 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges { } /** - * Returns an observable with the {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model used + * Returns the {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model used * for the authority field */ - getModel(): Observable { - return this.model$; + getModel(): DynamicOneboxModel | DynamicScrollableDropdownModel { + return this.model$.value; } /**