diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html index 1a7cc2e2df..7a4461b03b 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.html @@ -1,15 +1,26 @@ -
{{getRelationshipMessageKey() | async | translate}}
+
+ {{getRelationshipMessageKey() | async | translate}} + +
+ [ngClass]="{ + 'alert-success': updateValue.changeType === 1, + 'alert-warning': updateValue.changeType === 0, + 'alert-danger': updateValue.changeType === 2 + }"> +
{{"item.edit.relationships.no-relationships" | translate}}
-
no relationships
+
diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.scss b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.scss index e0c20d299f..54498499d7 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.scss +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.scss @@ -1,8 +1,8 @@ -.relationship-row:not(.alert-danger) { +.relationship-row:not(.alert) { padding: $alert-padding-y 0; } -.relationship-row.alert-danger { +.relationship-row.alert { margin-left: -$alert-padding-x; margin-right: -$alert-padding-x; margin-top: -1px; diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts index 1d4d91da0b..cd583fd22b 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.spec.ts @@ -1,5 +1,5 @@ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core'; -import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { TranslateModule } from '@ngx-translate/core'; import { of as observableOf } from 'rxjs/internal/observable/of'; @@ -8,6 +8,7 @@ import { FieldChangeType } from '../../../../core/data/object-updates/object-upd import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { PaginatedList } from '../../../../core/data/paginated-list'; import { RelationshipTypeService } from '../../../../core/data/relationship-type.service'; +import { RelationshipService } from '../../../../core/data/relationship.service'; import { RemoteData } from '../../../../core/data/remote-data'; import { ItemType } from '../../../../core/shared/item-relationships/item-type.model'; import { RelationshipType } from '../../../../core/shared/item-relationships/relationship-type.model'; @@ -15,6 +16,7 @@ import { Relationship } from '../../../../core/shared/item-relationships/relatio import { Item } from '../../../../core/shared/item.model'; import { PageInfo } from '../../../../core/shared/page-info.model'; import { getMockLinkService } from '../../../../shared/mocks/link-service.mock'; +import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service'; import { SharedModule } from '../../../../shared/shared.module'; import { EditRelationshipListComponent } from './edit-relationship-list.component'; @@ -22,72 +24,123 @@ let comp: EditRelationshipListComponent; let fixture: ComponentFixture; let de: DebugElement; +let linkService; let objectUpdatesService; -let entityTypeService; +let relationshipService; +let selectableListService; const url = 'http://test-url.com/test-url'; let item; +let entityType; +let relatedEntityType; let author1; let author2; let fieldUpdate1; let fieldUpdate2; -let relationship1; -let relationship2; +let relationships; let relationshipType; -let entityType; -let relatedEntityType; describe('EditRelationshipListComponent', () => { - beforeEach(() => { + beforeEach(async(() => { entityType = Object.assign(new ItemType(), { - id: 'entityType', + id: 'Publication', + uuid: 'Publication', + label: 'Publication', }); relatedEntityType = Object.assign(new ItemType(), { - id: 'relatedEntityType', + id: 'Author', + uuid: 'Author', + label: 'Author', }); relationshipType = Object.assign(new RelationshipType(), { id: '1', uuid: '1', + leftType: observableOf(new RemoteData( + false, + false, + true, + undefined, + entityType, + )), + rightType: observableOf(new RemoteData( + false, + false, + true, + undefined, + relatedEntityType, + )), leftwardType: 'isAuthorOfPublication', rightwardType: 'isPublicationOfAuthor', - leftType: observableOf(new RemoteData(false, false, true, undefined, entityType)), - rightType: observableOf(new RemoteData(false, false, true, undefined, relatedEntityType)), }); - relationship1 = Object.assign(new Relationship(), { - _links: { - self: { - href: url + '/2' - } - }, - id: '2', - uuid: '2', - leftId: 'author1', - rightId: 'publication', - leftItem: observableOf(new RemoteData(false, false, true, undefined, item)), - rightItem: observableOf(new RemoteData(false, false, true, undefined, author1)), - relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType)) + author1 = Object.assign(new Item(), { + id: 'author1', + uuid: 'author1' + }); + author2 = Object.assign(new Item(), { + id: 'author2', + uuid: 'author2' }); - relationship2 = Object.assign(new Relationship(), { - _links: { - self: { - href: url + '/3' - } - }, - id: '3', - uuid: '3', - leftId: 'author2', - rightId: 'publication', - leftItem: observableOf(new RemoteData(false, false, true, undefined, item)), - rightItem: observableOf(new RemoteData(false, false, true, undefined, author2)), - relationshipType: observableOf(new RemoteData(false, false, true, undefined, relationshipType)) - }); + relationships = [ + Object.assign(new Relationship(), { + self: url + '/2', + id: '2', + uuid: '2', + relationshipType: observableOf(new RemoteData( + false, + false, + true, + undefined, + relationshipType + )), + leftItem: observableOf(new RemoteData( + false, + false, + true, + undefined, + item, + )), + rightItem: observableOf(new RemoteData( + false, + false, + true, + undefined, + author1, + )), + }), + Object.assign(new Relationship(), { + self: url + '/3', + id: '3', + uuid: '3', + relationshipType: observableOf(new RemoteData( + false, + false, + true, + undefined, + relationshipType + )), + leftItem: observableOf(new RemoteData( + false, + false, + true, + undefined, + item, + )), + rightItem: observableOf(new RemoteData( + false, + false, + true, + undefined, + author2, + )), + }) + ]; item = Object.assign(new Item(), { _links: { @@ -100,84 +153,82 @@ describe('EditRelationshipListComponent', () => { false, true, undefined, - new PaginatedList(new PageInfo(), [relationship1, relationship2]) + new PaginatedList(new PageInfo(), relationships), )) }); - author1 = Object.assign(new Item(), { - id: 'author1', - uuid: 'author1' - }); - author2 = Object.assign(new Item(), { - id: 'author2', - uuid: 'author2' - }); - fieldUpdate1 = { - field: author1, + field: { + uuid: relationships[0].uuid, + relationship: relationships[0], + type: relationshipType, + }, changeType: undefined }; fieldUpdate2 = { - field: author2, + field: { + uuid: relationships[1].uuid, + relationship: relationships[1], + type: relationshipType, + }, changeType: FieldChangeType.REMOVE }; objectUpdatesService = jasmine.createSpyObj('objectUpdatesService', { getFieldUpdates: observableOf({ - [author1.uuid]: fieldUpdate1, - [author2.uuid]: fieldUpdate2 + [relationships[0].uuid]: fieldUpdate1, + [relationships[1].uuid]: fieldUpdate2 }) } ); - entityTypeService = jasmine.createSpyObj('entityTypeService', + relationshipService = jasmine.createSpyObj('relationshipService', { - getEntityTypeByLabel: observableOf(new RemoteData( - false, - false, - true, - null, - entityType, - )), - getEntityTypeRelationships: observableOf(new RemoteData( - false, - false, - true, - null, - new PaginatedList(new PageInfo(), [relationshipType]), - )), + getRelatedItemsByLabel: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), [author1, author2]))), + getItemRelationshipsByLabel: observableOf(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), relationships))), + isLeftItem: observableOf(true), } ); + selectableListService = {}; + + linkService = { + resolveLink: () => null, + resolveLinks: () => null, + }; + TestBed.configureTestingModule({ imports: [SharedModule, TranslateModule.forRoot()], declarations: [EditRelationshipListComponent], providers: [ { provide: ObjectUpdatesService, useValue: objectUpdatesService }, - { provide: RelationshipTypeService, useValue: {} }, - { provide: LinkService, useValue: getMockLinkService() }, + { provide: RelationshipService, useValue: relationshipService }, + { provide: SelectableListService, useValue: selectableListService }, + { provide: LinkService, useValue: linkService }, ], schemas: [ NO_ERRORS_SCHEMA ] }).compileComponents(); + })); + beforeEach(() => { fixture = TestBed.createComponent(EditRelationshipListComponent); comp = fixture.componentInstance; de = fixture.debugElement; - comp.item = item; comp.itemType = entityType; comp.url = url; comp.relationshipType = relationshipType; - fixture.detectChanges(); }); describe('changeType is REMOVE', () => { - it('the div should have class alert-danger', () => { - + beforeEach(() => { fieldUpdate1.changeType = FieldChangeType.REMOVE; + fixture.detectChanges(); + }); + it('the div should have class alert-danger', () => { const element = de.queryAll(By.css('.relationship-row'))[1].nativeElement; expect(element.classList).toContain('alert-danger'); }); diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts index c17762e4a0..59b4730018 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts @@ -1,11 +1,23 @@ import { Component, Input, OnInit } from '@angular/core'; +import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { LinkService } from '../../../../core/cache/builders/link.service'; +import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; import { Observable } from 'rxjs/internal/Observable'; -import {FieldUpdate, FieldUpdates} from '../../../../core/data/object-updates/object-updates.reducer'; +import { + FieldUpdate, + FieldUpdates, + RelationshipIdentifiable +} from '../../../../core/data/object-updates/object-updates.reducer'; +import { RelationshipService } from '../../../../core/data/relationship.service'; import {Item} from '../../../../core/shared/item.model'; -import { map, switchMap, tap } from 'rxjs/operators'; -import {hasValue} from '../../../../shared/empty.util'; +import { + defaultIfEmpty, filter, flatMap, + map, startWith, + switchMap, + take, tap, +} from 'rxjs/operators'; +import { hasValue, isNotEmptyOperator } from '../../../../shared/empty.util'; import {Relationship} from '../../../../core/shared/item-relationships/relationship.model'; import {RelationshipType} from '../../../../core/shared/item-relationships/relationship-type.model'; import { @@ -13,8 +25,13 @@ import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators'; -import { combineLatest as observableCombineLatest } from 'rxjs'; +import { combineLatest as observableCombineLatest, of } from 'rxjs'; import { ItemType } from '../../../../core/shared/item-relationships/item-type.model'; +import { DsDynamicLookupRelationModalComponent } from '../../../../shared/form/builder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.component'; +import { RelationshipOptions } from '../../../../shared/form/builder/models/relationship-options.model'; +import { ItemSearchResult } from '../../../../shared/object-collection/shared/item-search-result.model'; +import { SelectableListService } from '../../../../shared/object-list/selectable-list/selectable-list.service'; +import { SearchResult } from '../../../../shared/search/search-result.model'; import { followLink } from '../../../../shared/utils/follow-link-config.model'; @Component({ @@ -46,14 +63,29 @@ export class EditRelationshipListComponent implements OnInit { */ @Input() relationshipType: RelationshipType; + private relatedEntityType$: Observable; + + /** + * The list ID to save selected entities under + */ + listId: string; + /** * The FieldUpdates for the relationships in question */ updates$: Observable; + /** + * A reference to the lookup window + */ + modalRef: NgbModalRef; + constructor( protected objectUpdatesService: ObjectUpdatesService, - protected linkService: LinkService + protected linkService: LinkService, + protected relationshipService: RelationshipService, + protected modalService: NgbModal, + protected selectableListService: SelectableListService, ) { } @@ -77,7 +109,6 @@ export class EditRelationshipListComponent implements OnInit { * Get the relevant label for this relationship type */ private getLabel(): Observable { - return observableCombineLatest([ this.relationshipType.leftType, this.relationshipType.rightType, @@ -99,19 +130,189 @@ export class EditRelationshipListComponent implements OnInit { return update && update.field ? update.field.uuid : undefined; } + /** + * Open the dynamic lookup modal to search for items to add as relationships + */ + openLookup() { + + this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent, { + size: 'lg' + }); + const modalComp: DsDynamicLookupRelationModalComponent = this.modalRef.componentInstance; + modalComp.repeatable = true; + modalComp.listId = this.listId; + modalComp.item = this.item; + modalComp.select = (...selectableObjects: Array>) => { + selectableObjects.forEach((searchResult) => { + const relatedItem: Item = searchResult.indexableObject; + this.getFieldUpdatesForRelatedItem(relatedItem) + .subscribe((identifiables) => { + identifiables.forEach((identifiable) => + this.objectUpdatesService.removeSingleFieldUpdate(this.url, identifiable.uuid) + ); + if (identifiables.length === 0) { + this.relationshipService.getNameVariant(this.listId, relatedItem.uuid) + .subscribe((nameVariant) => { + const update = { + uuid: this.relationshipType.id + '-' + relatedItem.uuid, + nameVariant, + type: this.relationshipType, + relatedItem, + } as RelationshipIdentifiable; + this.objectUpdatesService.saveAddFieldUpdate(this.url, update); + }) + } + }); + }) + }; + modalComp.deselect = (...selectableObjects: Array>) => { + selectableObjects.forEach((searchResult) => { + const relatedItem: Item = searchResult.indexableObject; + this.objectUpdatesService.removeSingleFieldUpdate(this.url, this.relationshipType.id + '-' + relatedItem.uuid); + this.getFieldUpdatesForRelatedItem(relatedItem) + .subscribe((identifiables) => + identifiables.forEach((identifiable) => + this.objectUpdatesService.saveRemoveFieldUpdate(this.url, identifiable) + ) + ); + }) + }; + this.relatedEntityType$ + .pipe(take(1)) + .subscribe((relatedEntityType) => { + modalComp.relationshipOptions = Object.assign( + new RelationshipOptions(), { + relationshipType: relatedEntityType.label, + // filter: this.getRelationshipMessageKey(), + searchConfiguration: relatedEntityType.label.toLowerCase(), + nameVariants: true, + } + ); + }); + + this.selectableListService.deselectAll(this.listId); + this.updates$.pipe( + switchMap((updates) => observableCombineLatest( + Object.values(updates) + .filter((update) => update.changeType !== FieldChangeType.REMOVE) + .map((update) => { + const field = update.field as RelationshipIdentifiable; + if (field.relationship) { + return this.getRelatedItem(field.relationship); + } else { + return of(field.relatedItem); + } + }) + )), + take(1), + map((items) => items.map((item) => { + const searchResult = new ItemSearchResult(); + searchResult.indexableObject = item; + searchResult.hitHighlights = {}; + return searchResult; + })), + ).subscribe((items) => { + this.selectableListService.select(this.listId, items); + }); + } + + /** + * Get the existing field updates regarding a relationship with a given item + * @param relatedItem The item for which to get the existing field updates + */ + private getFieldUpdatesForRelatedItem(relatedItem: Item): Observable { + + return this.updates$.pipe( + take(1), + map((updates) => Object.values(updates) + .map((update) => update.field as RelationshipIdentifiable) + .filter((field) => field.relationship) + ), + flatMap((identifiables) => + observableCombineLatest( + identifiables.map((identifiable) => this.getRelatedItem(identifiable.relationship)) + ).pipe( + defaultIfEmpty([]), + map((relatedItems) => + identifiables.filter((identifiable, index) => relatedItems[index].uuid === relatedItem.uuid) + ), + ) + ), + ); + } + + /** + * Get the related item for a given relationship + * @param relationship The relationship for which to get the related item + */ + private getRelatedItem(relationship: Relationship): Observable { + return this.relationshipService.isLeftItem(relationship, this.item).pipe( + switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationship.leftItem), + getSucceededRemoteData(), + getRemoteDataPayload(), + ) + } + ngOnInit(): void { - this.updates$ = this.item.relationships.pipe( + this.listId = 'edit-relationship-' + this.itemType.id; + + this.relatedEntityType$ = + observableCombineLatest([ + this.relationshipType.leftType, + this.relationshipType.rightType, + ].map((type) => type.pipe( + getSucceededRemoteData(), + getRemoteDataPayload(), + ))).pipe( + map((relatedTypes) => relatedTypes.find((relatedType) => relatedType.uuid !== this.itemType.uuid)), + ); + + this.updates$ = this.getItemRelationships().pipe( + switchMap((relationships) => + observableCombineLatest( + relationships.map((relationship) => this.relationshipService.isLeftItem(relationship, this.item)) + ).pipe( + defaultIfEmpty([]), + map((isLeftItemArray) => isLeftItemArray.map((isLeftItem, index) => { + const relationship = relationships[index]; + const nameVariant = isLeftItem ? relationship.rightwardValue : relationship.leftwardValue; + return { + uuid: relationship.id, + type: this.relationshipType, + relationship, + nameVariant, + } as RelationshipIdentifiable + })), + )), + switchMap((initialFields) => this.objectUpdatesService.getFieldUpdates(this.url, initialFields).pipe( + map((fieldUpdates) => { + const fieldUpdatesFiltered: FieldUpdates = {}; + Object.keys(fieldUpdates).forEach((uuid) => { + const field = fieldUpdates[uuid].field; + if ((field as RelationshipIdentifiable).type.id === this.relationshipType.id) { + fieldUpdatesFiltered[uuid] = fieldUpdates[uuid]; + } + }); + return fieldUpdatesFiltered; + }), + )), + ); + } + + private getItemRelationships() { + this.linkService.resolveLink(this.item, followLink('relationships')); + return this.item.relationships.pipe( getAllSucceededRemoteData(), map((relationships) => relationships.payload.page.filter((relationship) => relationship)), - map((relationships: Relationship[]) => - relationships.map((relationship: Relationship) => { + filter((relationships) => relationships.every((relationship) => !!relationship)), + tap((relationships: Relationship[]) => + relationships.forEach((relationship: Relationship) => { this.linkService.resolveLinks( relationship, followLink('relationshipType'), followLink('leftItem'), followLink('rightItem'), ); - return relationship; }) ), switchMap((itemRelationships: Relationship[]) => @@ -122,15 +323,12 @@ export class EditRelationshipListComponent implements OnInit { getRemoteDataPayload(), )) ).pipe( + defaultIfEmpty([]), map((relationshipTypes) => itemRelationships.filter( (relationship, index) => relationshipTypes[index].id === this.relationshipType.id) ), - map((relationships) => relationships.map((relationship) => - Object.assign(new Relationship(), relationship, {uuid: relationship.id}) - )), ) ), - switchMap((initialFields) => this.objectUpdatesService.getFieldUpdates(this.url, initialFields)), ); } } diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html index 7e61e8958f..e65cd237a3 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.html @@ -1,6 +1,11 @@
- + +
diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts index 9eca3f270d..6e81319f28 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.spec.ts @@ -1,5 +1,5 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; -import { async, TestBed } from '@angular/core/testing'; +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { TranslateModule } from '@ngx-translate/core'; import { of as observableOf } from 'rxjs/internal/observable/of'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; @@ -25,7 +25,7 @@ let fieldUpdate2; let relationships; let relationshipType; -let fixture; +let fixture: ComponentFixture; let comp: EditRelationshipComponent; let de; let el; @@ -91,11 +91,17 @@ describe('EditRelationshipComponent', () => { }); fieldUpdate1 = { - field: relationships[0], + field: { + uuid: relationships[0].uuid, + relationship: relationships[0], + }, changeType: undefined }; fieldUpdate2 = { - field: relationships[1], + field: { + uuid: relationships[1].uuid, + relationship: relationships[1], + }, changeType: FieldChangeType.REMOVE }; diff --git a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts index 2badaf80b0..265bca7529 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts +++ b/src/app/+item-page/edit-item-page/item-relationships/edit-relationship/edit-relationship.component.ts @@ -1,10 +1,13 @@ import { Component, Input, OnChanges, OnInit } from '@angular/core'; -import { combineLatest as observableCombineLatest, Observable } from 'rxjs'; +import { combineLatest as observableCombineLatest, Observable, of } from 'rxjs'; import { filter, map, switchMap, take, tap } from 'rxjs/operators'; import { FieldChangeType } from '../../../../core/data/object-updates/object-updates.actions'; -import { DeleteRelationship, FieldUpdate } from '../../../../core/data/object-updates/object-updates.reducer'; +import { + DeleteRelationship, + FieldUpdate, + RelationshipIdentifiable +} from '../../../../core/data/object-updates/object-updates.reducer'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/object-updates.service'; -import { Relationship } from '../../../../core/shared/item-relationships/relationship.model'; import { Item } from '../../../../core/shared/item.model'; import { getRemoteDataPayload, getSucceededRemoteData } from '../../../../core/shared/operators'; import { ViewMode } from '../../../../core/shared/view-mode.model'; @@ -36,8 +39,16 @@ export class EditRelationshipComponent implements OnChanges { /** * The relationship being edited */ - get relationship(): Relationship { - return this.fieldUpdate.field as Relationship; + get relationship() { + return this.update.relationship; + } + + get update() { + return this.fieldUpdate.field as RelationshipIdentifiable; + } + + get nameVariant() { + return this.update.nameVariant; } public leftItem$: Observable; @@ -68,24 +79,28 @@ export class EditRelationshipComponent implements OnChanges { * Sets the current relationship based on the fieldUpdate input field */ ngOnChanges(): void { - this.leftItem$ = this.relationship.leftItem.pipe( - getSucceededRemoteData(), - getRemoteDataPayload(), - filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid)) - ); - this.rightItem$ = this.relationship.rightItem.pipe( - getSucceededRemoteData(), - getRemoteDataPayload(), - filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid)) - ); - this.relatedItem$ = observableCombineLatest( - this.leftItem$, - this.rightItem$, - ).pipe( - map((items: Item[]) => - items.find((item) => item.uuid !== this.editItem.uuid) - ) - ); + if (this.relationship) { + this.leftItem$ = this.relationship.leftItem.pipe( + getSucceededRemoteData(), + getRemoteDataPayload(), + filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid)) + ); + this.rightItem$ = this.relationship.rightItem.pipe( + getSucceededRemoteData(), + getRemoteDataPayload(), + filter((item: Item) => hasValue(item) && isNotEmpty(item.uuid)) + ); + this.relatedItem$ = observableCombineLatest( + this.leftItem$, + this.rightItem$, + ).pipe( + map((items: Item[]) => + items.find((item) => item.uuid !== this.editItem.uuid) + ) + ); + } else { + this.relatedItem$ = of(this.update.relatedItem); + } } /** @@ -136,7 +151,8 @@ export class EditRelationshipComponent implements OnChanges { * Check if a user should be allowed to remove this field */ canRemove(): boolean { - return this.fieldUpdate.changeType !== FieldChangeType.REMOVE; + return this.fieldUpdate.changeType !== FieldChangeType.REMOVE + && this.fieldUpdate.changeType !== FieldChangeType.ADD; } /** diff --git a/src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.html b/src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.html index 0c9d92dfbf..7692494fd8 100644 --- a/src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.html +++ b/src/app/+item-page/edit-item-page/item-relationships/item-relationships.component.html @@ -19,14 +19,19 @@  {{"item.edit.metadata.save-button" | translate}}
-
- -
+ + +
+ +
+
+ +