Merge pull request #2900 from toniprieto/edit-item-authorities-bug-model

Error loading the initial value when editing an authority field in edit item page
This commit is contained in:
Tim Donohue
2024-05-09 14:57:12 -05:00
committed by GitHub
3 changed files with 75 additions and 77 deletions

View File

@@ -9,12 +9,12 @@
<ds-dynamic-scrollable-dropdown *ngIf="mdValue.editing && (isScrollableVocabulary() | async)" <ds-dynamic-scrollable-dropdown *ngIf="mdValue.editing && (isScrollableVocabulary() | async)"
[bindId]="mdField" [bindId]="mdField"
[group]="group" [group]="group"
[model]="getModel() | async" [model]="getModel()"
(change)="onChangeAuthorityField($event)"> (change)="onChangeAuthorityField($event)">
</ds-dynamic-scrollable-dropdown> </ds-dynamic-scrollable-dropdown>
<ds-dynamic-onebox *ngIf="mdValue.editing && ((isHierarchicalVocabulary() | async) || (isSuggesterVocabulary() | async))" <ds-dynamic-onebox *ngIf="mdValue.editing && ((isHierarchicalVocabulary() | async) || (isSuggesterVocabulary() | async))"
[group]="group" [group]="group"
[model]="getModel() | async" [model]="getModel()"
(change)="onChangeAuthorityField($event)"> (change)="onChangeAuthorityField($event)">
</ds-dynamic-onebox> </ds-dynamic-onebox>
<div *ngIf="!isVirtual && !mdValue.editing && mdValue.newValue.authority && mdValue.newValue.confidence !== ConfidenceTypeEnum.CF_UNSET && mdValue.newValue.confidence !== ConfidenceTypeEnum.CF_NOVALUE"> <div *ngIf="!isVirtual && !mdValue.editing && mdValue.newValue.authority && mdValue.newValue.confidence !== ConfidenceTypeEnum.CF_UNSET && mdValue.newValue.confidence !== ConfidenceTypeEnum.CF_NOVALUE">

View File

@@ -10,10 +10,7 @@ import {
import { By } from '@angular/platform-browser'; import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { import { of } from 'rxjs';
Observable,
of,
} from 'rxjs';
import { MetadataField } from 'src/app/core/metadata/metadata-field.model'; import { MetadataField } from 'src/app/core/metadata/metadata-field.model';
import { MetadataSchema } from 'src/app/core/metadata/metadata-schema.model'; import { MetadataSchema } from 'src/app/core/metadata/metadata-schema.model';
import { RegistryService } from 'src/app/core/registry/registry.service'; import { RegistryService } from 'src/app/core/registry/registry.service';
@@ -346,14 +343,11 @@ describe('DsoEditMetadataValueComponent', () => {
}); });
it('getModel should return a DynamicScrollableDropdownModel', () => { it('getModel should return a DynamicScrollableDropdownModel', () => {
const result = component.getModel(); const model = component.getModel();
expect(result instanceof Observable).toBe(true);
result.subscribe((model) => {
expect(model instanceof DynamicScrollableDropdownModel).toBe(true); expect(model instanceof DynamicScrollableDropdownModel).toBe(true);
expect(model.vocabularyOptions.name).toBe(mockVocabularyScrollable.name); expect(model.vocabularyOptions.name).toBe(mockVocabularyScrollable.name);
});
}); });
}); });
@@ -380,16 +374,12 @@ describe('DsoEditMetadataValueComponent', () => {
}); });
it('getModel should return a DynamicOneboxModel', () => { it('getModel should return a DynamicOneboxModel', () => {
const result = component.getModel(); const model = component.getModel();
expect(result instanceof Observable).toBe(true);
result.subscribe((model) => {
expect(model instanceof DynamicOneboxModel).toBe(true); expect(model instanceof DynamicOneboxModel).toBe(true);
expect(model.vocabularyOptions.name).toBe(mockVocabularyHierarchical.name); expect(model.vocabularyOptions.name).toBe(mockVocabularyHierarchical.name);
}); });
}); });
});
describe('when the metadata field uses a suggester vocabulary and is editing', () => { describe('when the metadata field uses a suggester vocabulary and is editing', () => {
beforeEach(waitForAsync(() => { beforeEach(waitForAsync(() => {
@@ -416,15 +406,11 @@ describe('DsoEditMetadataValueComponent', () => {
}); });
it('getModel should return a DynamicOneboxModel', () => { it('getModel should return a DynamicOneboxModel', () => {
const result = component.getModel(); const model = component.getModel();
expect(result instanceof Observable).toBe(true);
result.subscribe((model) => {
expect(model instanceof DynamicOneboxModel).toBe(true); expect(model instanceof DynamicOneboxModel).toBe(true);
expect(model.vocabularyOptions.name).toBe(mockVocabularySuggester.name); expect(model.vocabularyOptions.name).toBe(mockVocabularySuggester.name);
}); });
});
describe('authority key edition', () => { describe('authority key edition', () => {

View File

@@ -29,6 +29,7 @@ import {
TranslateService, TranslateService,
} from '@ngx-translate/core'; } from '@ngx-translate/core';
import { import {
BehaviorSubject,
EMPTY, EMPTY,
Observable, Observable,
of as observableOf, of as observableOf,
@@ -37,6 +38,7 @@ import {
map, map,
switchMap, switchMap,
take, take,
tap,
} from 'rxjs/operators'; } from 'rxjs/operators';
import { RegistryService } from 'src/app/core/registry/registry.service'; import { RegistryService } from 'src/app/core/registry/registry.service';
import { VocabularyService } from 'src/app/core/submission/vocabularies/vocabulary.service'; import { VocabularyService } from 'src/app/core/submission/vocabularies/vocabulary.service';
@@ -196,9 +198,9 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
group = new UntypedFormGroup({ authorityField : new UntypedFormControl() }); 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<DynamicOneboxModel | DynamicScrollableDropdownModel>; private model$: BehaviorSubject<DynamicOneboxModel | DynamicScrollableDropdownModel> = new BehaviorSubject(null);
/** /**
* Observable with information about the authority vocabulary used * Observable with information about the authority vocabulary used
@@ -278,6 +280,8 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
} }
this.isAuthorityControlled$ = this.vocabulary$.pipe( 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)), map((result: Vocabulary) => isNotEmpty(result)),
); );
@@ -293,8 +297,14 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
map((result: Vocabulary) => isNotEmpty(result) && !result.hierarchical && !result.scrollable), map((result: Vocabulary) => isNotEmpty(result) && !result.hierarchical && !result.scrollable),
); );
this.model$ = this.vocabulary$.pipe( }
map((vocabulary: Vocabulary) => {
/**
* Returns a {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model based on the
* vocabulary used.
*/
private createModel(vocabulary: Vocabulary): DynamicOneboxModel | DynamicScrollableDropdownModel {
if (isNotEmpty(vocabulary)) {
let formFieldValue; let formFieldValue;
if (isNotEmpty(this.mdValue.newValue.value)) { if (isNotEmpty(this.mdValue.newValue.value)) {
formFieldValue = new FormFieldMetadataValueObject(); formFieldValue = new FormFieldMetadataValueObject();
@@ -340,7 +350,9 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
}; };
return new DynamicScrollableDropdownModel(model); return new DynamicScrollableDropdownModel(model);
} }
})); } else {
return null;
}
} }
/** /**
@@ -438,11 +450,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 * for the authority field
*/ */
getModel(): Observable<DynamicOneboxModel | DynamicScrollableDropdownModel> { getModel(): DynamicOneboxModel | DynamicScrollableDropdownModel {
return this.model$; return this.model$.value;
} }
/** /**