From 807500db41a98585dbeda18a9dadd773d7257ed7 Mon Sep 17 00:00:00 2001 From: Art Lowel Date: Mon, 6 Apr 2020 18:11:27 +0200 Subject: [PATCH] fix issue where results wouldn't update after a name variant change --- src/app/core/data/relationship.service.ts | 49 +++++++++++++------ ...amic-form-control-container.component.html | 2 +- .../relationship.effects.ts | 2 +- ...etadata-representation-loader.component.ts | 17 ++++++- 4 files changed, 50 insertions(+), 20 deletions(-) diff --git a/src/app/core/data/relationship.service.ts b/src/app/core/data/relationship.service.ts index 61bd717518..fab8db4286 100644 --- a/src/app/core/data/relationship.service.ts +++ b/src/app/core/data/relationship.service.ts @@ -66,6 +66,19 @@ const relationshipStateSelector = (listID: string, itemID: string): MemoizedSele return keySelector(itemID, relationshipListStateSelector(listID)); }; +/** + * Return true if the Item in the payload of the source observable matches + * the given Item by UUID + * + * @param itemCheck the Item to compare with + */ +const compareItemsByUUID = (itemCheck: Item) => + (source: Observable>): Observable => + source.pipe( + getFirstSucceededRemoteDataPayload(), + map((item: Item) => item.uuid === itemCheck.uuid) + ); + /** * The service handling all relationship requests */ @@ -125,7 +138,6 @@ export class RelationshipService extends DataService { * @param rightwardValue The rightward value of the relationship */ addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable { - console.log('addRelationship', typeId, item1, item2, leftwardValue, rightwardValue); const options: HttpOptions = Object.create({}); let headers = new HttpHeaders(); headers = headers.append('Content-Type', 'text/uri-list'); @@ -172,10 +184,10 @@ export class RelationshipService extends DataService { public refreshRelationshipItemsInCache(item) { this.objectCache.remove(item._links.self.href); this.requestService.removeByHrefSubstring(item.uuid); - observableCombineLatest( + observableCombineLatest([ this.objectCache.hasBySelfLinkObservable(item._links.self.href), this.requestService.hasByHrefObservable(item.self) - ).pipe( + ]).pipe( filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC), take(1), switchMap(() => this.itemService.findByHref(item._links.self.href).pipe(take(1))) @@ -184,7 +196,10 @@ export class RelationshipService extends DataService { /** * Get an item's relationships in the form of an array - * @param item + * + * @param item The {@link Item} to get {@link Relationship}s for + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s + * should be automatically resolved */ getItemRelationshipsArray(item: Item, ...linksToFollow: Array>): Observable { return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe( @@ -283,10 +298,10 @@ export class RelationshipService extends DataService { getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable { return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem')).pipe( switchMap((relationships: Relationship[]) => { - return observableCombineLatest(...relationships.map((relationship: Relationship) => { + return observableCombineLatest(relationships.map((relationship: Relationship) => { const isLeftItem$ = this.isItemInUUIDArray(relationship.leftItem, uuids); const isRightItem$ = this.isItemInUUIDArray(relationship.rightItem, uuids); - return observableCombineLatest(isLeftItem$, isRightItem$).pipe( + return observableCombineLatest([isLeftItem$, isRightItem$]).pipe( filter(([isLeftItem, isRightItem]) => isLeftItem || isRightItem), map(() => relationship), startWith(undefined) @@ -312,7 +327,6 @@ export class RelationshipService extends DataService { * @param label The rightward or leftward type of the relationship */ getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string, options?: FindListOptions): Observable { - console.log('getRelationshipByItemsAndLabel', item1, item2, label, options); return this.getItemRelationshipsByLabel( item1, label, @@ -326,8 +340,8 @@ export class RelationshipService extends DataService { mergeMap((relationshipListRD: RemoteData>) => relationshipListRD.payload.page), mergeMap((relationship: Relationship) => { return observableCombineLatest([ - this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.leftItem.href), item2), - this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.rightItem.href), item2) + this.itemService.findByHref(relationship._links.leftItem.href).pipe(compareItemsByUUID(item2)), + this.itemService.findByHref(relationship._links.rightItem.href).pipe(compareItemsByUUID(item2)) ]).pipe( map(([isLeftItem, isRightItem]) => isLeftItem || isRightItem), map((isMatch) => isMatch ? relationship : undefined) @@ -338,13 +352,6 @@ export class RelationshipService extends DataService { ) } - private isItemMatchWithItemRD(itemRD$: Observable>, itemCheck: Item): Observable { - return itemRD$.pipe( - getFirstSucceededRemoteDataPayload(), - map((item: Item) => item.uuid === itemCheck.uuid) - ); - } - /** * Method to set the name variant for specific list and item * @param listID The list for which to save the name variant @@ -441,4 +448,14 @@ export class RelationshipService extends DataService { return update$; } + + + /** + * Patch isn't supported on the relationship endpoint, so use put instead. + * + * @param object the {@link Relationship} to update + */ + update(object: Relationship): Observable> { + return this.put(object); + } } diff --git a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html index 4dd0951d70..c2595f603e 100644 --- a/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html +++ b/src/app/shared/form/builder/ds-dynamic-form-ui/ds-dynamic-form-control-container.component.html @@ -44,7 +44,7 @@ ) => hasValue(relationshipRD.payload)), take(1) - ).subscribe(() => { + ).subscribe((c) => { this.updateAfterPatchSubmissionId = submissionId; this.relationshipService.refreshRelationshipItemsInCache(item1); this.relationshipService.refreshRelationshipItemsInCache(item2); diff --git a/src/app/shared/metadata-representation/metadata-representation-loader.component.ts b/src/app/shared/metadata-representation/metadata-representation-loader.component.ts index 86bede6789..c091534f62 100644 --- a/src/app/shared/metadata-representation/metadata-representation-loader.component.ts +++ b/src/app/shared/metadata-representation/metadata-representation-loader.component.ts @@ -5,6 +5,7 @@ import { Context } from '../../core/shared/context.model'; import { GenericConstructor } from '../../core/shared/generic-constructor'; import { MetadataRepresentationListElementComponent } from '../object-list/metadata-representation-list-element/metadata-representation-list-element.component'; import { MetadataRepresentationDirective } from './metadata-representation.directive'; +import { hasValue } from '../empty.util'; @Component({ selector: 'ds-metadata-representation-loader', @@ -15,10 +16,21 @@ import { MetadataRepresentationDirective } from './metadata-representation.direc * Component for determining what component to use depending on the item's relationship type (relationship.type), its metadata representation and, optionally, its context */ export class MetadataRepresentationLoaderComponent implements OnInit { + private componentRefInstance: MetadataRepresentationListElementComponent; + /** * The item or metadata to determine the component for */ - @Input() mdRepresentation: MetadataRepresentation; + private _mdRepresentation: MetadataRepresentation; + get mdRepresentation(): MetadataRepresentation { + return this._mdRepresentation; + } + @Input() set mdRepresentation(nextValue: MetadataRepresentation) { + this._mdRepresentation = nextValue; + if (hasValue(this.componentRefInstance)) { + this.componentRefInstance.metadataRepresentation = nextValue; + } + } /** * The optional context @@ -43,7 +55,8 @@ export class MetadataRepresentationLoaderComponent implements OnInit { viewContainerRef.clear(); const componentRef = viewContainerRef.createComponent(componentFactory); - (componentRef.instance as MetadataRepresentationListElementComponent).metadataRepresentation = this.mdRepresentation; + this.componentRefInstance = componentRef.instance as MetadataRepresentationListElementComponent; + this.componentRefInstance.metadataRepresentation = this.mdRepresentation; } /**