fix issue where results wouldn't update after a name variant change

This commit is contained in:
Art Lowel
2020-04-06 18:11:27 +02:00
parent 2a58f2480a
commit 807500db41
4 changed files with 50 additions and 20 deletions

View File

@@ -66,6 +66,19 @@ const relationshipStateSelector = (listID: string, itemID: string): MemoizedSele
return keySelector<string>(itemID, relationshipListStateSelector(listID)); return keySelector<string>(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<RemoteData<Item>>): Observable<boolean> =>
source.pipe(
getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid === itemCheck.uuid)
);
/** /**
* The service handling all relationship requests * The service handling all relationship requests
*/ */
@@ -125,7 +138,6 @@ export class RelationshipService extends DataService<Relationship> {
* @param rightwardValue The rightward value of the relationship * @param rightwardValue The rightward value of the relationship
*/ */
addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> { addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> {
console.log('addRelationship', typeId, item1, item2, leftwardValue, rightwardValue);
const options: HttpOptions = Object.create({}); const options: HttpOptions = Object.create({});
let headers = new HttpHeaders(); let headers = new HttpHeaders();
headers = headers.append('Content-Type', 'text/uri-list'); headers = headers.append('Content-Type', 'text/uri-list');
@@ -172,10 +184,10 @@ export class RelationshipService extends DataService<Relationship> {
public refreshRelationshipItemsInCache(item) { public refreshRelationshipItemsInCache(item) {
this.objectCache.remove(item._links.self.href); this.objectCache.remove(item._links.self.href);
this.requestService.removeByHrefSubstring(item.uuid); this.requestService.removeByHrefSubstring(item.uuid);
observableCombineLatest( observableCombineLatest([
this.objectCache.hasBySelfLinkObservable(item._links.self.href), this.objectCache.hasBySelfLinkObservable(item._links.self.href),
this.requestService.hasByHrefObservable(item.self) this.requestService.hasByHrefObservable(item.self)
).pipe( ]).pipe(
filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC), filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC),
take(1), take(1),
switchMap(() => this.itemService.findByHref(item._links.self.href).pipe(take(1))) switchMap(() => this.itemService.findByHref(item._links.self.href).pipe(take(1)))
@@ -184,7 +196,10 @@ export class RelationshipService extends DataService<Relationship> {
/** /**
* Get an item's relationships in the form of an array * 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<FollowLinkConfig<Relationship>>): Observable<Relationship[]> { getItemRelationshipsArray(item: Item, ...linksToFollow: Array<FollowLinkConfig<Relationship>>): Observable<Relationship[]> {
return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe( return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe(
@@ -283,10 +298,10 @@ export class RelationshipService extends DataService<Relationship> {
getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> { getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> {
return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem')).pipe( return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem')).pipe(
switchMap((relationships: Relationship[]) => { switchMap((relationships: Relationship[]) => {
return observableCombineLatest(...relationships.map((relationship: Relationship) => { return observableCombineLatest(relationships.map((relationship: Relationship) => {
const isLeftItem$ = this.isItemInUUIDArray(relationship.leftItem, uuids); const isLeftItem$ = this.isItemInUUIDArray(relationship.leftItem, uuids);
const isRightItem$ = this.isItemInUUIDArray(relationship.rightItem, uuids); const isRightItem$ = this.isItemInUUIDArray(relationship.rightItem, uuids);
return observableCombineLatest(isLeftItem$, isRightItem$).pipe( return observableCombineLatest([isLeftItem$, isRightItem$]).pipe(
filter(([isLeftItem, isRightItem]) => isLeftItem || isRightItem), filter(([isLeftItem, isRightItem]) => isLeftItem || isRightItem),
map(() => relationship), map(() => relationship),
startWith(undefined) startWith(undefined)
@@ -312,7 +327,6 @@ export class RelationshipService extends DataService<Relationship> {
* @param label The rightward or leftward type of the relationship * @param label The rightward or leftward type of the relationship
*/ */
getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string, options?: FindListOptions): Observable<Relationship> { getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string, options?: FindListOptions): Observable<Relationship> {
console.log('getRelationshipByItemsAndLabel', item1, item2, label, options);
return this.getItemRelationshipsByLabel( return this.getItemRelationshipsByLabel(
item1, item1,
label, label,
@@ -326,8 +340,8 @@ export class RelationshipService extends DataService<Relationship> {
mergeMap((relationshipListRD: RemoteData<PaginatedList<Relationship>>) => relationshipListRD.payload.page), mergeMap((relationshipListRD: RemoteData<PaginatedList<Relationship>>) => relationshipListRD.payload.page),
mergeMap((relationship: Relationship) => { mergeMap((relationship: Relationship) => {
return observableCombineLatest([ return observableCombineLatest([
this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.leftItem.href), item2), this.itemService.findByHref(relationship._links.leftItem.href).pipe(compareItemsByUUID(item2)),
this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.rightItem.href), item2) this.itemService.findByHref(relationship._links.rightItem.href).pipe(compareItemsByUUID(item2))
]).pipe( ]).pipe(
map(([isLeftItem, isRightItem]) => isLeftItem || isRightItem), map(([isLeftItem, isRightItem]) => isLeftItem || isRightItem),
map((isMatch) => isMatch ? relationship : undefined) map((isMatch) => isMatch ? relationship : undefined)
@@ -338,13 +352,6 @@ export class RelationshipService extends DataService<Relationship> {
) )
} }
private isItemMatchWithItemRD(itemRD$: Observable<RemoteData<Item>>, itemCheck: Item): Observable<boolean> {
return itemRD$.pipe(
getFirstSucceededRemoteDataPayload(),
map((item: Item) => item.uuid === itemCheck.uuid)
);
}
/** /**
* Method to set the name variant for specific list and item * Method to set the name variant for specific list and item
* @param listID The list for which to save the name variant * @param listID The list for which to save the name variant
@@ -441,4 +448,14 @@ export class RelationshipService extends DataService<Relationship> {
return update$; 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<RemoteData<Relationship>> {
return this.put(object);
}
} }

View File

@@ -44,7 +44,7 @@
<ng-container *ngIf="value?.isVirtual"> <ng-container *ngIf="value?.isVirtual">
<ds-existing-metadata-list-element <ds-existing-metadata-list-element
[reoRel]="relationshipValue$ | async" [reoRel]="relationshipValue$ | async"
[submissionItem]="item" [submissionItem]="item$ | async"
[listId]="listId" [listId]="listId"
[metadataFields]="model.metadataFields" [metadataFields]="model.metadataFields"
[submissionId]="model.submissionId" [submissionId]="model.submissionId"

View File

@@ -105,7 +105,7 @@ export class RelationshipEffects {
this.relationshipService.updateNameVariant(item1, item2, relationshipType, nameVariant).pipe( this.relationshipService.updateNameVariant(item1, item2, relationshipType, nameVariant).pipe(
filter((relationshipRD: RemoteData<Relationship>) => hasValue(relationshipRD.payload)), filter((relationshipRD: RemoteData<Relationship>) => hasValue(relationshipRD.payload)),
take(1) take(1)
).subscribe(() => { ).subscribe((c) => {
this.updateAfterPatchSubmissionId = submissionId; this.updateAfterPatchSubmissionId = submissionId;
this.relationshipService.refreshRelationshipItemsInCache(item1); this.relationshipService.refreshRelationshipItemsInCache(item1);
this.relationshipService.refreshRelationshipItemsInCache(item2); this.relationshipService.refreshRelationshipItemsInCache(item2);

View File

@@ -5,6 +5,7 @@ import { Context } from '../../core/shared/context.model';
import { GenericConstructor } from '../../core/shared/generic-constructor'; import { GenericConstructor } from '../../core/shared/generic-constructor';
import { MetadataRepresentationListElementComponent } from '../object-list/metadata-representation-list-element/metadata-representation-list-element.component'; import { MetadataRepresentationListElementComponent } from '../object-list/metadata-representation-list-element/metadata-representation-list-element.component';
import { MetadataRepresentationDirective } from './metadata-representation.directive'; import { MetadataRepresentationDirective } from './metadata-representation.directive';
import { hasValue } from '../empty.util';
@Component({ @Component({
selector: 'ds-metadata-representation-loader', 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 * 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 { export class MetadataRepresentationLoaderComponent implements OnInit {
private componentRefInstance: MetadataRepresentationListElementComponent;
/** /**
* The item or metadata to determine the component for * 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 * The optional context
@@ -43,7 +55,8 @@ export class MetadataRepresentationLoaderComponent implements OnInit {
viewContainerRef.clear(); viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory); const componentRef = viewContainerRef.createComponent(componentFactory);
(componentRef.instance as MetadataRepresentationListElementComponent).metadataRepresentation = this.mdRepresentation; this.componentRefInstance = componentRef.instance as MetadataRepresentationListElementComponent;
this.componentRefInstance.metadataRepresentation = this.mdRepresentation;
} }
/** /**