{{ mdRepresentationName$ | async }}
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 e96959c1d1f..c64599f8b51 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
@@ -8,41 +8,26 @@ import {
waitForAsync,
} from '@angular/core/testing';
import { By } from '@angular/platform-browser';
-import { RouterTestingModule } from '@angular/router/testing';
+import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
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';
-import { ConfidenceType } from 'src/app/core/shared/confidence-type';
-import { Vocabulary } from 'src/app/core/submission/vocabularies/models/vocabulary.model';
-import { VocabularyService } from 'src/app/core/submission/vocabularies/vocabulary.service';
-import { DynamicOneboxModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.model';
-import { DynamicScrollableDropdownModel } from 'src/app/shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
-import { NotificationsService } from 'src/app/shared/notifications/notifications.service';
-import { createPaginatedList } from 'src/app/shared/testing/utils.test';
-import { VocabularyServiceStub } from 'src/app/shared/testing/vocabulary-service.stub';
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
-import { ItemDataService } from '../../../core/data/item-data.service';
import { RelationshipDataService } from '../../../core/data/relationship-data.service';
-import { Collection } from '../../../core/shared/collection.model';
-import { DSpaceObject } from '../../../core/shared/dspace-object.model';
-import { Item } from '../../../core/shared/item.model';
import {
MetadataValue,
VIRTUAL_METADATA_PREFIX,
} from '../../../core/shared/metadata.models';
import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model';
-import { DsDynamicOneboxComponent } from '../../../shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component';
-import { DsDynamicScrollableDropdownComponent } from '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
import { ThemedTypeBadgeComponent } from '../../../shared/object-collection/shared/badges/type-badge/themed-type-badge.component';
-import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
+import { DsoEditMetadataFieldServiceStub } from '../../../shared/testing/dso-edit-metadata-field.service.stub';
import { VarDirective } from '../../../shared/utils/var.directive';
import {
DsoEditMetadataChangeType,
DsoEditMetadataValue,
} from '../dso-edit-metadata-form';
+import { DsoEditMetadataFieldService } from '../dso-edit-metadata-value-field/dso-edit-metadata-field.service';
+import { DsoEditMetadataValueFieldLoaderComponent } from '../dso-edit-metadata-value-field/dso-edit-metadata-value-field-loader/dso-edit-metadata-value-field-loader.component';
import { DsoEditMetadataValueComponent } from './dso-edit-metadata-value.component';
const EDIT_BTN = 'edit';
@@ -57,97 +42,12 @@ describe('DsoEditMetadataValueComponent', () => {
let relationshipService: RelationshipDataService;
let dsoNameService: DSONameService;
- let vocabularyServiceStub: any;
- let itemService: ItemDataService;
- let registryService: RegistryService;
- let notificationsService: NotificationsService;
+ let dsoEditMetadataFieldService: DsoEditMetadataFieldServiceStub;
let editMetadataValue: DsoEditMetadataValue;
let metadataValue: MetadataValue;
- let dso: DSpaceObject;
-
- const collection = Object.assign(new Collection(), {
- uuid: 'fake-uuid',
- });
-
- const item = Object.assign(new Item(), {
- _links: {
- self: { href: 'fake-item-url/item' },
- },
- id: 'item',
- uuid: 'item',
- owningCollection: createSuccessfulRemoteDataObject$(collection),
- });
-
- const mockVocabularyScrollable: Vocabulary = {
- id: 'scrollable',
- name: 'scrollable',
- scrollable: true,
- hierarchical: false,
- preloadLevel: 0,
- type: 'vocabulary',
- _links: {
- self: {
- href: 'self',
- },
- entries: {
- href: 'entries',
- },
- },
- };
-
- const mockVocabularyHierarchical: Vocabulary = {
- id: 'hierarchical',
- name: 'hierarchical',
- scrollable: false,
- hierarchical: true,
- preloadLevel: 2,
- type: 'vocabulary',
- _links: {
- self: {
- href: 'self',
- },
- entries: {
- href: 'entries',
- },
- },
- };
-
- const mockVocabularySuggester: Vocabulary = {
- id: 'suggester',
- name: 'suggester',
- scrollable: false,
- hierarchical: false,
- preloadLevel: 0,
- type: 'vocabulary',
- _links: {
- self: {
- href: 'self',
- },
- entries: {
- href: 'entries',
- },
- },
- };
-
- let metadataSchema: MetadataSchema;
- let metadataFields: MetadataField[];
function initServices(): void {
- metadataSchema = Object.assign(new MetadataSchema(), {
- id: 0,
- prefix: 'metadata',
- namespace: 'http://example.com/',
- });
- metadataFields = [
- Object.assign(new MetadataField(), {
- id: 0,
- element: 'regular',
- qualifier: null,
- schema: createSuccessfulRemoteDataObject$(metadataSchema),
- }),
- ];
-
relationshipService = jasmine.createSpyObj('relationshipService', {
resolveMetadataRepresentation: of(
new ItemMetadataRepresentation(metadataValue),
@@ -156,14 +56,7 @@ describe('DsoEditMetadataValueComponent', () => {
dsoNameService = jasmine.createSpyObj('dsoNameService', {
getName: 'Related Name',
});
- itemService = jasmine.createSpyObj('itemService', {
- findByHref: createSuccessfulRemoteDataObject$(item),
- });
- vocabularyServiceStub = new VocabularyServiceStub();
- registryService = jasmine.createSpyObj('registryService', {
- queryMetadataFields: createSuccessfulRemoteDataObject$(createPaginatedList(metadataFields)),
- });
- notificationsService = jasmine.createSpyObj('notificationsService', ['error', 'success']);
+ dsoEditMetadataFieldService = new DsoEditMetadataFieldServiceStub();
}
beforeEach(waitForAsync(async () => {
@@ -174,34 +67,29 @@ describe('DsoEditMetadataValueComponent', () => {
authority: undefined,
});
editMetadataValue = new DsoEditMetadataValue(metadataValue);
- dso = Object.assign(new DSpaceObject(), {
- _links: {
- self: { href: 'fake-dso-url/dso' },
- },
- });
initServices();
await TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot(),
- RouterTestingModule.withRoutes([]),
+ RouterModule.forRoot([]),
DsoEditMetadataValueComponent,
VarDirective,
],
providers: [
{ provide: RelationshipDataService, useValue: relationshipService },
{ provide: DSONameService, useValue: dsoNameService },
- { provide: VocabularyService, useValue: vocabularyServiceStub },
- { provide: ItemDataService, useValue: itemService },
- { provide: RegistryService, useValue: registryService },
- { provide: NotificationsService, useValue: notificationsService },
+ { provide: DsoEditMetadataFieldService, useValue: dsoEditMetadataFieldService },
],
schemas: [NO_ERRORS_SCHEMA],
})
.overrideComponent(DsoEditMetadataValueComponent, {
remove: {
- imports: [DsDynamicOneboxComponent, DsDynamicScrollableDropdownComponent, ThemedTypeBadgeComponent],
+ imports: [
+ DsoEditMetadataValueFieldLoaderComponent,
+ ThemedTypeBadgeComponent,
+ ],
},
})
.compileComponents();
@@ -211,7 +99,6 @@ describe('DsoEditMetadataValueComponent', () => {
fixture = TestBed.createComponent(DsoEditMetadataValueComponent);
component = fixture.componentInstance;
component.mdValue = editMetadataValue;
- component.dso = dso;
component.saving$ = of(false);
fixture.detectChanges();
});
@@ -297,219 +184,6 @@ describe('DsoEditMetadataValueComponent', () => {
assertButton(DRAG_BTN, true, false);
});
- describe('when the metadata field not uses a vocabulary and is editing', () => {
- beforeEach(waitForAsync(() => {
- spyOn(vocabularyServiceStub, 'getVocabularyByMetadataAndCollection').and.returnValue(createSuccessfulRemoteDataObject$(null, 204));
- metadataValue = Object.assign(new MetadataValue(), {
- value: 'Regular value',
- language: 'en',
- place: 0,
- authority: null,
- });
- editMetadataValue = new DsoEditMetadataValue(metadataValue);
- editMetadataValue.editing = true;
- component.mdValue = editMetadataValue;
- component.mdField = 'metadata.regular';
- component.ngOnInit();
- fixture.detectChanges();
- }));
-
- it('should render a textarea', () => {
- expect(vocabularyServiceStub.getVocabularyByMetadataAndCollection).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('textarea'))).toBeTruthy();
- });
- });
-
- describe('when the metadata field uses a scrollable vocabulary and is editing', () => {
- beforeEach(waitForAsync(() => {
- spyOn(vocabularyServiceStub, 'getVocabularyByMetadataAndCollection').and.returnValue(createSuccessfulRemoteDataObject$(mockVocabularyScrollable));
- metadataValue = Object.assign(new MetadataValue(), {
- value: 'Authority Controlled value',
- language: 'en',
- place: 0,
- authority: null,
- });
- editMetadataValue = new DsoEditMetadataValue(metadataValue);
- editMetadataValue.editing = true;
- component.mdValue = editMetadataValue;
- component.mdField = 'metadata.scrollable';
- component.ngOnInit();
- fixture.detectChanges();
- }));
-
- it('should render the DsDynamicScrollableDropdownComponent', () => {
- expect(vocabularyServiceStub.getVocabularyByMetadataAndCollection).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('ds-dynamic-scrollable-dropdown'))).toBeTruthy();
- });
-
- it('getModel should return a DynamicScrollableDropdownModel', () => {
- const model = component.getModel();
-
- expect(model instanceof DynamicScrollableDropdownModel).toBe(true);
- expect(model.vocabularyOptions.name).toBe(mockVocabularyScrollable.name);
-
- });
- });
-
- describe('when the metadata field uses a hierarchical vocabulary and is editing', () => {
- beforeEach(waitForAsync(() => {
- spyOn(vocabularyServiceStub, 'getVocabularyByMetadataAndCollection').and.returnValue(createSuccessfulRemoteDataObject$(mockVocabularyHierarchical));
- metadataValue = Object.assign(new MetadataValue(), {
- value: 'Authority Controlled value',
- language: 'en',
- place: 0,
- authority: null,
- });
- editMetadataValue = new DsoEditMetadataValue(metadataValue);
- editMetadataValue.editing = true;
- component.mdValue = editMetadataValue;
- component.mdField = 'metadata.hierarchical';
- component.ngOnInit();
- fixture.detectChanges();
- }));
-
- it('should render the DsDynamicOneboxComponent', () => {
- expect(vocabularyServiceStub.getVocabularyByMetadataAndCollection).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('ds-dynamic-onebox'))).toBeTruthy();
- });
-
- it('getModel should return a DynamicOneboxModel', () => {
- const model = component.getModel();
-
- expect(model instanceof DynamicOneboxModel).toBe(true);
- expect(model.vocabularyOptions.name).toBe(mockVocabularyHierarchical.name);
- });
- });
-
- describe('when the metadata field uses a suggester vocabulary and is editing', () => {
- beforeEach(waitForAsync(() => {
- spyOn(vocabularyServiceStub, 'getVocabularyByMetadataAndCollection').and.returnValue(createSuccessfulRemoteDataObject$(mockVocabularySuggester));
- spyOn(component.confirm, 'emit');
- metadataValue = Object.assign(new MetadataValue(), {
- value: 'Authority Controlled value',
- language: 'en',
- place: 0,
- authority: 'authority-key',
- confidence: ConfidenceType.CF_UNCERTAIN,
- });
- editMetadataValue = new DsoEditMetadataValue(metadataValue);
- editMetadataValue.editing = true;
- component.mdValue = editMetadataValue;
- component.mdField = 'metadata.suggester';
- component.ngOnInit();
- fixture.detectChanges();
- }));
-
- it('should render the DsDynamicOneboxComponent', () => {
- expect(vocabularyServiceStub.getVocabularyByMetadataAndCollection).toHaveBeenCalled();
- expect(fixture.debugElement.query(By.css('ds-dynamic-onebox'))).toBeTruthy();
- });
-
- it('getModel should return a DynamicOneboxModel', () => {
- const model = component.getModel();
-
- expect(model instanceof DynamicOneboxModel).toBe(true);
- expect(model.vocabularyOptions.name).toBe(mockVocabularySuggester.name);
- });
-
- describe('authority key edition', () => {
-
- it('should update confidence to CF_NOVALUE when authority is cleared', () => {
- component.mdValue.newValue.authority = '';
-
- component.onChangeAuthorityKey();
-
- expect(component.mdValue.newValue.confidence).toBe(ConfidenceType.CF_NOVALUE);
- expect(component.confirm.emit).toHaveBeenCalledWith(false);
- });
-
- it('should update confidence to CF_ACCEPTED when authority key is edited', () => {
- component.mdValue.newValue.authority = 'newAuthority';
- component.mdValue.originalValue.authority = 'oldAuthority';
-
- component.onChangeAuthorityKey();
-
- expect(component.mdValue.newValue.confidence).toBe(ConfidenceType.CF_ACCEPTED);
- expect(component.confirm.emit).toHaveBeenCalledWith(false);
- });
-
- it('should not update confidence when authority key remains the same', () => {
- component.mdValue.newValue.authority = 'sameAuthority';
- component.mdValue.originalValue.authority = 'sameAuthority';
-
- component.onChangeAuthorityKey();
-
- expect(component.mdValue.newValue.confidence).toBe(ConfidenceType.CF_UNCERTAIN);
- expect(component.confirm.emit).not.toHaveBeenCalled();
- });
-
- it('should call onChangeEditingAuthorityStatus with true when clicking the lock button', () => {
- spyOn(component, 'onChangeEditingAuthorityStatus');
- const lockButton = fixture.nativeElement.querySelector('#metadata-confirm-btn');
-
- lockButton.click();
-
- expect(component.onChangeEditingAuthorityStatus).toHaveBeenCalledWith(true);
- });
-
- it('should disable the input when editingAuthority is false', (done) => {
- component.editingAuthority = false;
-
- fixture.detectChanges();
-
- fixture.detectChanges();
- fixture.whenStable().then(() => {
- const inputElement = fixture.nativeElement.querySelector('input[data-test="authority-input"]');
- expect(inputElement.disabled).toBeTruthy();
- done();
- });
- });
-
- it('should enable the input when editingAuthority is true', (done) => {
- component.editingAuthority = true;
-
- fixture.detectChanges();
- fixture.whenStable().then(() => {
- const inputElement = fixture.nativeElement.querySelector('input[data-test="authority-input"]');
- expect(inputElement.disabled).toBeFalsy();
- done();
- });
-
-
- });
-
- it('should update mdValue.newValue properties when authority is present', () => {
- const event = {
- value: 'Some value',
- authority: 'Some authority',
- };
-
- component.onChangeAuthorityField(event);
-
- expect(component.mdValue.newValue.value).toBe(event.value);
- expect(component.mdValue.newValue.authority).toBe(event.authority);
- expect(component.mdValue.newValue.confidence).toBe(ConfidenceType.CF_ACCEPTED);
- expect(component.confirm.emit).toHaveBeenCalledWith(false);
- });
-
- it('should update mdValue.newValue properties when authority is not present', () => {
- const event = {
- value: 'Some value',
- authority: null,
- };
-
- component.onChangeAuthorityField(event);
-
- expect(component.mdValue.newValue.value).toBe(event.value);
- expect(component.mdValue.newValue.authority).toBeNull();
- expect(component.mdValue.newValue.confidence).toBe(ConfidenceType.CF_UNSET);
- expect(component.confirm.emit).toHaveBeenCalledWith(false);
- });
-
- });
-
- });
-
function assertButton(name: string, exists: boolean, disabled: boolean = false): void {
describe(`${name} button`, () => {
let btn: DebugElement;
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 11bbcfd9d5e..192440397c9 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
@@ -8,7 +8,6 @@ import {
NgIf,
} from '@angular/common';
import {
- ChangeDetectorRef,
Component,
EventEmitter,
Input,
@@ -17,95 +16,67 @@ import {
Output,
SimpleChanges,
} from '@angular/core';
-import {
- FormsModule,
- UntypedFormControl,
- UntypedFormGroup,
-} from '@angular/forms';
+import { FormsModule } from '@angular/forms';
import { RouterLink } from '@angular/router';
import { NgbTooltipModule } from '@ng-bootstrap/ng-bootstrap';
+import { TranslateModule } from '@ngx-translate/core';
import {
- TranslateModule,
- TranslateService,
-} from '@ngx-translate/core';
-import {
- BehaviorSubject,
EMPTY,
Observable,
- of as observableOf,
} from 'rxjs';
-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';
-import { NotificationsService } from 'src/app/shared/notifications/notifications.service';
+import { map } from 'rxjs/operators';
import { DSONameService } from '../../../core/breadcrumbs/dso-name.service';
-import { ItemDataService } from '../../../core/data/item-data.service';
import { RelationshipDataService } from '../../../core/data/relationship-data.service';
import { MetadataService } from '../../../core/metadata/metadata.service';
-import { Collection } from '../../../core/shared/collection.model';
import { ConfidenceType } from '../../../core/shared/confidence-type';
+import { Context } from '../../../core/shared/context.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
-import { Item } from '../../../core/shared/item.model';
import { ItemMetadataRepresentation } from '../../../core/shared/metadata-representation/item/item-metadata-representation.model';
import {
MetadataRepresentation,
MetadataRepresentationType,
} from '../../../core/shared/metadata-representation/metadata-representation.model';
-import {
- getFirstCompletedRemoteData,
- getFirstSucceededRemoteData,
- getFirstSucceededRemoteDataPayload,
- getRemoteDataPayload,
- metadataFieldsToString,
-} from '../../../core/shared/operators';
import { Vocabulary } from '../../../core/submission/vocabularies/models/vocabulary.model';
-import { VocabularyOptions } from '../../../core/submission/vocabularies/models/vocabulary-options.model';
import { getItemPageRoute } from '../../../item-page/item-page-routing-paths';
-import { isNotEmpty } from '../../../shared/empty.util';
-import { DsDynamicOneboxComponent } from '../../../shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.component';
-import {
- DsDynamicOneboxModelConfig,
- DynamicOneboxModel,
-} from '../../../shared/form/builder/ds-dynamic-form-ui/models/onebox/dynamic-onebox.model';
-import { DsDynamicScrollableDropdownComponent } from '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.component';
-import {
- DynamicScrollableDropdownModel,
- DynamicScrollableDropdownModelConfig,
-} from '../../../shared/form/builder/ds-dynamic-form-ui/models/scrollable-dropdown/dynamic-scrollable-dropdown.model';
-import { FormFieldMetadataValueObject } from '../../../shared/form/builder/models/form-field-metadata-value.model';
+import { hasValue } from '../../../shared/empty.util';
import { AuthorityConfidenceStateDirective } from '../../../shared/form/directives/authority-confidence-state.directive';
import { ThemedTypeBadgeComponent } from '../../../shared/object-collection/shared/badges/type-badge/themed-type-badge.component';
import { DebounceDirective } from '../../../shared/utils/debounce.directive';
-import { followLink } from '../../../shared/utils/follow-link-config.model';
import { VarDirective } from '../../../shared/utils/var.directive';
import {
DsoEditMetadataChangeType,
DsoEditMetadataValue,
} from '../dso-edit-metadata-form';
+import { DsoEditMetadataFieldService } from '../dso-edit-metadata-value-field/dso-edit-metadata-field.service';
+import { EditMetadataValueFieldType } from '../dso-edit-metadata-value-field/dso-edit-metadata-field-type.enum';
+import { DsoEditMetadataValueFieldLoaderComponent } from '../dso-edit-metadata-value-field/dso-edit-metadata-value-field-loader/dso-edit-metadata-value-field-loader.component';
@Component({
selector: 'ds-dso-edit-metadata-value',
styleUrls: ['./dso-edit-metadata-value.component.scss', '../dso-edit-metadata-shared/dso-edit-metadata-cells.scss'],
templateUrl: './dso-edit-metadata-value.component.html',
standalone: true,
- imports: [VarDirective, CdkDrag, NgClass, NgIf, FormsModule, DebounceDirective, RouterLink, ThemedTypeBadgeComponent, NgbTooltipModule, CdkDragHandle, AsyncPipe, TranslateModule, DsDynamicScrollableDropdownComponent, DsDynamicOneboxComponent, AuthorityConfidenceStateDirective],
+ imports: [VarDirective, CdkDrag, NgClass, NgIf, FormsModule, DebounceDirective, RouterLink, ThemedTypeBadgeComponent, NgbTooltipModule, CdkDragHandle, AsyncPipe, TranslateModule, DsoEditMetadataValueFieldLoaderComponent, AuthorityConfidenceStateDirective],
})
/**
* Component displaying a single editable row for a metadata value
*/
export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
+
+ @Input() context: Context;
+
/**
* The parent {@link DSpaceObject} to display a metadata form for
* Also used to determine metadata-representations in case of virtual metadata
*/
@Input() dso: DSpaceObject;
+ /**
+ * The metadata field that is being edited
+ */
+ @Input() mdField: string;
+
/**
* Editable metadata value to show
*/
@@ -129,11 +100,6 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
*/
@Input() isOnlyValue = false;
- /**
- * MetadataField to edit
- */
- @Input() mdField?: string;
-
/**
* Emits when the user clicked edit
*/
@@ -165,12 +131,6 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
*/
public DsoEditMetadataChangeTypeEnum = DsoEditMetadataChangeType;
- /**
- * The ConfidenceType enumeration for access in the component's template
- * @type {ConfidenceType}
- */
- public ConfidenceTypeEnum = ConfidenceType;
-
/**
* The item this metadata value represents in case it's virtual (if any, otherwise null)
*/
@@ -187,50 +147,28 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
mdRepresentationName$: Observable
;
/**
- * Whether or not the authority field is currently being edited
- */
- public editingAuthority = false;
-
- /**
- * Field group used by authority field
- * @type {UntypedFormGroup}
- */
- group = new UntypedFormGroup({ authorityField : new UntypedFormControl() });
-
- /**
- * Model to use for editing authorities values
- */
- private model$: BehaviorSubject = new BehaviorSubject(null);
-
- /**
- * Observable with information about the authority vocabulary used
+ * The type of edit field that should be displayed
*/
- private vocabulary$: Observable;
+ fieldType$: Observable;
- /**
- * Observables with information about the authority vocabulary type used
- */
- private isAuthorityControlled$: Observable;
- private isHierarchicalVocabulary$: Observable;
- private isScrollableVocabulary$: Observable;
- private isSuggesterVocabulary$: Observable;
+ readonly ConfidenceTypeEnum = ConfidenceType;
constructor(
protected relationshipService: RelationshipDataService,
protected dsoNameService: DSONameService,
- protected vocabularyService: VocabularyService,
- protected itemService: ItemDataService,
- protected cdr: ChangeDetectorRef,
- protected registryService: RegistryService,
- protected notificationsService: NotificationsService,
- protected translate: TranslateService,
protected metadataService: MetadataService,
+ protected dsoEditMetadataFieldService: DsoEditMetadataFieldService,
) {
}
ngOnInit(): void {
this.initVirtualProperties();
- this.initAuthorityProperties();
+ }
+
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes.mdField) {
+ this.fieldType$ = this.getFieldType();
+ }
}
/**
@@ -253,231 +191,20 @@ export class DsoEditMetadataValueComponent implements OnInit, OnChanges {
}
/**
- * Initialise potential properties of a authority controlled metadata field
- */
- initAuthorityProperties(): void {
-
- if (isNotEmpty(this.mdField)) {
-
- const owningCollection$: Observable = this.itemService.findByHref(this.dso._links.self.href, true, true, followLink('owningCollection'))
- .pipe(
- getFirstSucceededRemoteData(),
- getRemoteDataPayload(),
- switchMap((item: Item) => item.owningCollection),
- getFirstSucceededRemoteData(),
- getRemoteDataPayload(),
- );
-
- this.vocabulary$ = owningCollection$.pipe(
- switchMap((c: Collection) => this.vocabularyService
- .getVocabularyByMetadataAndCollection(this.mdField, c.uuid)
- .pipe(
- getFirstSucceededRemoteDataPayload(),
- )),
- );
- } else {
- this.vocabulary$ = observableOf(undefined);
- }
-
- 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)),
- );
-
- this.isHierarchicalVocabulary$ = this.vocabulary$.pipe(
- map((result: Vocabulary) => isNotEmpty(result) && result.hierarchical),
- );
-
- this.isScrollableVocabulary$ = this.vocabulary$.pipe(
- map((result: Vocabulary) => isNotEmpty(result) && result.scrollable),
- );
-
- this.isSuggesterVocabulary$ = this.vocabulary$.pipe(
- map((result: Vocabulary) => isNotEmpty(result) && !result.hierarchical && !result.scrollable),
- );
-
- }
-
- /**
- * Returns a {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model based on the
- * vocabulary used.
+ * Retrieves the {@link EditMetadataValueFieldType} to be displayed for the current field while in edit mode.
*/
- 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;
+ getFieldType(): Observable {
+ return this.dsoEditMetadataFieldService.findDsoFieldVocabulary(this.dso, this.mdField).pipe(
+ map((vocabulary: Vocabulary) => {
+ if (hasValue(vocabulary)) {
+ return EditMetadataValueFieldType.AUTHORITY;
}
- } 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;
- }
- }
-
- /**
- * Change callback for the component. Check if the mdField has changed to retrieve whether it is metadata
- * that uses a controlled vocabulary and update the related properties
- *
- * @param {SimpleChanges} changes
- */
- ngOnChanges(changes: SimpleChanges): void {
- if (isNotEmpty(changes.mdField) && !changes.mdField.firstChange) {
- if (isNotEmpty(changes.mdField.currentValue) ) {
- if (isNotEmpty(changes.mdField.previousValue) &&
- changes.mdField.previousValue !== changes.mdField.currentValue) {
- // Clear authority value in case it has been assigned with the previous metadataField used
- this.mdValue.newValue.authority = null;
- this.mdValue.newValue.confidence = ConfidenceType.CF_UNSET;
- }
-
- // Only ask if the current mdField have a period character to reduce request
- if (changes.mdField.currentValue.includes('.')) {
- this.validateMetadataField().subscribe((isValid: boolean) => {
- if (isValid) {
- this.initAuthorityProperties();
- this.cdr.detectChanges();
- }
- });
- }
- }
- }
- }
-
- /**
- * Validate the metadata field to check if it exists on the server and return an observable boolean for success/error
- */
- validateMetadataField(): Observable {
- return this.registryService.queryMetadataFields(this.mdField, null, true, false, followLink('schema')).pipe(
- getFirstCompletedRemoteData(),
- switchMap((rd) => {
- if (rd.hasSucceeded) {
- return observableOf(rd).pipe(
- metadataFieldsToString(),
- take(1),
- map((fields: string[]) => fields.indexOf(this.mdField) > -1),
- );
- } else {
- this.notificationsService.error(this.translate.instant(`${this.dsoType}.edit.metadata.metadatafield.error`), rd.errorMessage);
- return [false];
+ if (this.mdField === 'dspace.entity.type') {
+ return EditMetadataValueFieldType.ENTITY_TYPE;
}
+ return EditMetadataValueFieldType.PLAIN_TEXT;
}),
);
}
- /**
- * Checks if this field use a authority vocabulary
- */
- isAuthorityControlled(): Observable {
- return this.isAuthorityControlled$;
- }
-
- /**
- * Checks if configured vocabulary is Hierarchical or not
- */
- isHierarchicalVocabulary(): Observable {
- return this.isHierarchicalVocabulary$;
- }
-
- /**
- * Checks if configured vocabulary is Scrollable or not
- */
- isScrollableVocabulary(): Observable {
- return this.isScrollableVocabulary$;
- }
-
- /**
- * Checks if configured vocabulary is Suggester or not
- * (a vocabulary not Scrollable and not Hierarchical that uses an autocomplete field)
- */
- isSuggesterVocabulary(): Observable {
- return this.isSuggesterVocabulary$;
- }
-
- /**
- * Process the change of authority field value updating the authority key and confidence as necessary
- */
- onChangeAuthorityField(event): void {
- this.mdValue.newValue.value = event.value;
- if (event.authority) {
- this.mdValue.newValue.authority = event.authority;
- this.mdValue.newValue.confidence = ConfidenceType.CF_ACCEPTED;
- } else {
- this.mdValue.newValue.authority = null;
- this.mdValue.newValue.confidence = ConfidenceType.CF_UNSET;
- }
- this.confirm.emit(false);
- }
-
- /**
- * Returns the {@link DynamicOneboxModel} or {@link DynamicScrollableDropdownModel} model used
- * for the authority field
- */
- getModel(): DynamicOneboxModel | DynamicScrollableDropdownModel {
- return this.model$.value;
- }
-
- /**
- * Change the status of the editingAuthority property
- * @param status
- */
- onChangeEditingAuthorityStatus(status: boolean) {
- this.editingAuthority = status;
- }
-
- /**
- * Processes the change in authority value, updating the confidence as necessary.
- * If the authority key is cleared, the confidence is set to {@link ConfidenceType.CF_NOVALUE}.
- * If the authority key is edited and differs from the original, the confidence is set to {@link ConfidenceType.CF_ACCEPTED}.
- */
- onChangeAuthorityKey() {
- if (this.mdValue.newValue.authority === '') {
- this.mdValue.newValue.confidence = ConfidenceType.CF_NOVALUE;
- this.confirm.emit(false);
- } else if (this.mdValue.newValue.authority !== this.mdValue.originalValue.authority) {
- this.mdValue.newValue.confidence = ConfidenceType.CF_ACCEPTED;
- this.confirm.emit(false);
- }
- }
-
}
diff --git a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html
index f8b193f4a05..2416a806a8b 100644
--- a/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html
+++ b/src/app/dso-shared/dso-edit-metadata/dso-edit-metadata.component.html
@@ -40,6 +40,7 @@
{
+ return observableOf(undefined);
+ }
+
+}
diff --git a/src/app/shared/testing/entity-type-data.service.stub.ts b/src/app/shared/testing/entity-type-data.service.stub.ts
index 367eeb5f743..d558dc3c31d 100644
--- a/src/app/shared/testing/entity-type-data.service.stub.ts
+++ b/src/app/shared/testing/entity-type-data.service.stub.ts
@@ -1,5 +1,20 @@
+import { Observable } from 'rxjs';
+
+import { FindListOptions } from '../../core/data/find-list-options.model';
+import { PaginatedList } from '../../core/data/paginated-list.model';
+import { RemoteData } from '../../core/data/remote-data';
+import { ItemType } from '../../core/shared/item-relationships/item-type.model';
+import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
+import { FollowLinkConfig } from '../utils/follow-link-config.model';
+import { createPaginatedList } from './utils.test';
+
/**
* Stub class of {@link EntityTypeDataService}
*/
export class EntityTypeDataServiceStub {
+
+ public findAll(_options?: FindListOptions, _useCachedVersionIfAvailable?: boolean, _reRequestOnStale?: boolean, ..._linksToFollow: FollowLinkConfig[]): Observable>> {
+ return createSuccessfulRemoteDataObject$(createPaginatedList());
+ }
+
}