Commits

Art Lowel authored 807500db41a
fix issue where results wouldn't update after a name variant change
No tags

src/app/core/data/relationship.service.ts

Modified
59 59 const relationshipListsStateSelector = (state: AppState) => state.relationshipLists;
60 60
61 61 const relationshipListStateSelector = (listID: string): MemoizedSelector<AppState, NameVariantListState> => {
62 62 return keySelector<NameVariantListState>(listID, relationshipListsStateSelector);
63 63 };
64 64
65 65 const relationshipStateSelector = (listID: string, itemID: string): MemoizedSelector<AppState, string> => {
66 66 return keySelector<string>(itemID, relationshipListStateSelector(listID));
67 67 };
68 68
69 +/**
70 + * Return true if the Item in the payload of the source observable matches
71 + * the given Item by UUID
72 + *
73 + * @param itemCheck the Item to compare with
74 + */
75 +const compareItemsByUUID = (itemCheck: Item) =>
76 + (source: Observable<RemoteData<Item>>): Observable<boolean> =>
77 + source.pipe(
78 + getFirstSucceededRemoteDataPayload(),
79 + map((item: Item) => item.uuid === itemCheck.uuid)
80 + );
81 +
69 82 /**
70 83 * The service handling all relationship requests
71 84 */
72 85 @Injectable()
73 86 @dataService(RELATIONSHIP)
74 87 export class RelationshipService extends DataService<Relationship> {
75 88 protected linkPath = 'relationships';
76 89
77 90 constructor(protected itemService: ItemDataService,
78 91 protected requestService: RequestService,
118 131
119 132 /**
120 133 * Method to create a new relationship
121 134 * @param typeId The identifier of the relationship type
122 135 * @param item1 The first item of the relationship
123 136 * @param item2 The second item of the relationship
124 137 * @param leftwardValue The leftward value of the relationship
125 138 * @param rightwardValue The rightward value of the relationship
126 139 */
127 140 addRelationship(typeId: string, item1: Item, item2: Item, leftwardValue?: string, rightwardValue?: string): Observable<RestResponse> {
128 - console.log('addRelationship', typeId, item1, item2, leftwardValue, rightwardValue);
129 141 const options: HttpOptions = Object.create({});
130 142 let headers = new HttpHeaders();
131 143 headers = headers.append('Content-Type', 'text/uri-list');
132 144 options.headers = headers;
133 145 return this.halService.getEndpoint(this.linkPath).pipe(
134 146 isNotEmptyOperator(),
135 147 take(1),
136 148 map((endpointUrl: string) => `${endpointUrl}?relationshipType=${typeId}`),
137 149 map((endpointUrl: string) => isNotEmpty(leftwardValue) ? `${endpointUrl}&leftwardValue=${leftwardValue}` : endpointUrl),
138 150 map((endpointUrl: string) => isNotEmpty(rightwardValue) ? `${endpointUrl}&rightwardValue=${rightwardValue}` : endpointUrl),
165 177 })
166 178 }
167 179
168 180 /**
169 181 * Method to remove an item that's part of a relationship from the cache
170 182 * @param item The item to remove from the cache
171 183 */
172 184 public refreshRelationshipItemsInCache(item) {
173 185 this.objectCache.remove(item._links.self.href);
174 186 this.requestService.removeByHrefSubstring(item.uuid);
175 - observableCombineLatest(
187 + observableCombineLatest([
176 188 this.objectCache.hasBySelfLinkObservable(item._links.self.href),
177 189 this.requestService.hasByHrefObservable(item.self)
178 - ).pipe(
190 + ]).pipe(
179 191 filter(([existsInOC, existsInRC]) => !existsInOC && !existsInRC),
180 192 take(1),
181 193 switchMap(() => this.itemService.findByHref(item._links.self.href).pipe(take(1)))
182 194 ).subscribe();
183 195 }
184 196
185 197 /**
186 198 * Get an item's relationships in the form of an array
187 - * @param item
199 + *
200 + * @param item The {@link Item} to get {@link Relationship}s for
201 + * @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s
202 + * should be automatically resolved
188 203 */
189 204 getItemRelationshipsArray(item: Item, ...linksToFollow: Array<FollowLinkConfig<Relationship>>): Observable<Relationship[]> {
190 205 return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe(
191 206 getSucceededRemoteData(),
192 207 getRemoteDataPayload(),
193 208 map((rels: PaginatedList<Relationship>) => rels.page),
194 209 hasValueOperator(),
195 210 distinctUntilChanged(compareArraysUsingIds()),
196 211 );
197 212 }
276 291
277 292 /**
278 293 * Method for fetching an item's relationships, but filtered by related item IDs (essentially performing a reverse lookup)
279 294 * Only relationships where leftItem or rightItem's ID is present in the list provided will be returned
280 295 * @param item
281 296 * @param uuids
282 297 */
283 298 getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> {
284 299 return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem')).pipe(
285 300 switchMap((relationships: Relationship[]) => {
286 - return observableCombineLatest(...relationships.map((relationship: Relationship) => {
301 + return observableCombineLatest(relationships.map((relationship: Relationship) => {
287 302 const isLeftItem$ = this.isItemInUUIDArray(relationship.leftItem, uuids);
288 303 const isRightItem$ = this.isItemInUUIDArray(relationship.rightItem, uuids);
289 - return observableCombineLatest(isLeftItem$, isRightItem$).pipe(
304 + return observableCombineLatest([isLeftItem$, isRightItem$]).pipe(
290 305 filter(([isLeftItem, isRightItem]) => isLeftItem || isRightItem),
291 306 map(() => relationship),
292 307 startWith(undefined)
293 308 );
294 309 }))
295 310 }),
296 311 map((relationships: Relationship[]) => relationships.filter(((relationship) => hasValue(relationship)))),
297 312 )
298 313 }
299 314
305 320 );
306 321 }
307 322
308 323 /**
309 324 * Method to retrieve a relationship based on two items and a relationship type label
310 325 * @param item1 The first item in the relationship
311 326 * @param item2 The second item in the relationship
312 327 * @param label The rightward or leftward type of the relationship
313 328 */
314 329 getRelationshipByItemsAndLabel(item1: Item, item2: Item, label: string, options?: FindListOptions): Observable<Relationship> {
315 - console.log('getRelationshipByItemsAndLabel', item1, item2, label, options);
316 330 return this.getItemRelationshipsByLabel(
317 331 item1,
318 332 label,
319 333 options,
320 334 followLink('relationshipType'),
321 335 followLink('leftItem'),
322 336 followLink('rightItem')
323 337 ).pipe(
324 338 getSucceededRemoteData(),
325 339 // the mergemap below will emit all elements of the list as separate events
326 340 mergeMap((relationshipListRD: RemoteData<PaginatedList<Relationship>>) => relationshipListRD.payload.page),
327 341 mergeMap((relationship: Relationship) => {
328 342 return observableCombineLatest([
329 - this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.leftItem.href), item2),
330 - this.isItemMatchWithItemRD(this.itemService.findByHref(relationship._links.rightItem.href), item2)
343 + this.itemService.findByHref(relationship._links.leftItem.href).pipe(compareItemsByUUID(item2)),
344 + this.itemService.findByHref(relationship._links.rightItem.href).pipe(compareItemsByUUID(item2))
331 345 ]).pipe(
332 346 map(([isLeftItem, isRightItem]) => isLeftItem || isRightItem),
333 347 map((isMatch) => isMatch ? relationship : undefined)
334 348 );
335 349 }),
336 350 filter((relationship) => hasValue(relationship)),
337 351 take(1)
338 352 )
339 353 }
340 354
341 - private isItemMatchWithItemRD(itemRD$: Observable<RemoteData<Item>>, itemCheck: Item): Observable<boolean> {
342 - return itemRD$.pipe(
343 - getFirstSucceededRemoteDataPayload(),
344 - map((item: Item) => item.uuid === itemCheck.uuid)
345 - );
346 - }
347 -
348 355 /**
349 356 * Method to set the name variant for specific list and item
350 357 * @param listID The list for which to save the name variant
351 358 * @param itemID The item ID for which to save the name variant
352 359 * @param nameVariant The name variant to save
353 360 */
354 361 public setNameVariant(listID: string, itemID: string, nameVariant: string) {
355 362 this.appStore.dispatch(new SetNameVariantAction(listID, itemID, nameVariant));
356 363 }
357 364
434 441 filter((relationshipRD: RemoteData<Relationship>) => relationshipRD.state === RemoteDataState.ResponsePending),
435 442 take(1),
436 443 ).subscribe((relationshipRD: RemoteData<Relationship>) => {
437 444 if (relationshipRD.state === RemoteDataState.ResponsePending) {
438 445 this.refreshRelationshipItemsInCacheByRelationship(reoRel.relationship.id);
439 446 }
440 447 });
441 448
442 449 return update$;
443 450 }
451 +
452 +
453 + /**
454 + * Patch isn't supported on the relationship endpoint, so use put instead.
455 + *
456 + * @param object the {@link Relationship} to update
457 + */
458 + update(object: Relationship): Observable<RemoteData<Relationship>> {
459 + return this.put(object);
460 + }
444 461 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut