fix links for relationships

This commit is contained in:
Art Lowel
2020-01-23 14:24:13 +01:00
parent 1d31cae970
commit b2f966eb83
14 changed files with 50 additions and 28 deletions

View File

@@ -74,7 +74,7 @@ export const paginatedRelationsToItems = (thisId: string) =>
source.pipe(
getSucceededRemoteData(),
switchMap((relationshipsRD: RemoteData<PaginatedList<Relationship>>) => {
return observableZip(
return observableCombineLatest(
...relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem))
).pipe(
map((arr) =>

View File

@@ -15,6 +15,12 @@ export class LinkService {
) {
}
public resolveLinks<T extends HALResource>(model: T, ...linksToFollow: Array<FollowLinkConfig<T>>) {
linksToFollow.forEach((linkToFollow: FollowLinkConfig<T>) => {
this.resolveLink(model, linkToFollow);
});
}
public resolveLink<T extends HALResource>(model, linkToFollow: FollowLinkConfig<T>) {
const matchingLinkDef = getLinkDefinition(model.constructor, linkToFollow.name);

View File

@@ -227,9 +227,7 @@ export class RemoteDataBuildService {
const domainModelConstructor = getMapsTo(normalized.constructor);
const domainModel = Object.assign(new domainModelConstructor(), normalized, halLinks);
linksToFollow.forEach((linkToFollow: FollowLinkConfig<T>) => {
this.linkService.resolveLink(domainModel, linkToFollow);
});
this.linkService.resolveLinks(domainModel, ...linksToFollow);
return domainModel;
}

View File

@@ -15,6 +15,7 @@ import { ObjectCacheService } from '../cache/object-cache.service';
@Injectable()
export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
protected toCache = false;
protected shouldDirectlyAttachEmbeds = true;
constructor(
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,

View File

@@ -16,6 +16,7 @@ export abstract class BaseResponseParsingService {
protected abstract EnvConfig: GlobalConfig;
protected abstract objectCache: ObjectCacheService;
protected abstract toCache: boolean;
protected shouldDirectlyAttachEmbeds = false;
protected process<ObjectDomain>(data: any, request: RestRequest): any {
if (isNotEmpty(data)) {
@@ -32,7 +33,17 @@ export abstract class BaseResponseParsingService {
.keys(data._embedded)
.filter((property) => data._embedded.hasOwnProperty(property))
.forEach((property) => {
this.process<ObjectDomain>(data._embedded[property], request);
const parsedObj = this.process<ObjectDomain>(data._embedded[property], request);
if (this.shouldDirectlyAttachEmbeds && isNotEmpty(parsedObj)) {
if (isRestPaginatedList(data._embedded[property])) {
object[property] = parsedObj;
object[property].page = parsedObj.page.map((obj) => this.retrieveObjectOrUrl(obj));
} else if (isRestDataObject(data._embedded[property])) {
object[property] = this.retrieveObjectOrUrl(parsedObj);
} else if (Array.isArray(parsedObj)) {
object[property] = parsedObj.map((obj) => this.retrieveObjectOrUrl(obj))
}
}
});
}

View File

@@ -9,7 +9,6 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
import { DataService } from './data.service';
import { RemoteData } from './remote-data';
import { RequestService } from './request.service';
import { FindListOptions } from './request.models';
import { ObjectCacheService } from '../cache/object-cache.service';
import { NotificationsService } from '../../shared/notifications/notifications.service';
import { HttpClient } from '@angular/common/http';

View File

@@ -1,6 +1,6 @@
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { followLink } from '../../shared/utils/follow-link-config.model';
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
import { dataService } from '../cache/builders/build-decorators';
import { MemoizedSelector, select, Store } from '@ngrx/store';
import { combineLatest, combineLatest as observableCombineLatest } from 'rxjs';
@@ -167,8 +167,8 @@ export class RelationshipService extends DataService<Relationship> {
* Get an item's relationships in the form of an array
* @param item
*/
getItemRelationshipsArray(item: Item): Observable<Relationship[]> {
return this.findAllByHref(item._links.relationships.href).pipe(
getItemRelationshipsArray(item: Item, ...linksToFollow: Array<FollowLinkConfig<Relationship>>): Observable<Relationship[]> {
return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe(
getSucceededRemoteData(),
getRemoteDataPayload(),
map((rels: PaginatedList<Relationship>) => rels.page),
@@ -183,7 +183,7 @@ export class RelationshipService extends DataService<Relationship> {
* @param item
*/
getRelationshipTypeLabelsByItem(item: Item): Observable<string[]> {
return this.getItemRelationshipsArray(item).pipe(
return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')).pipe(
switchMap((relationships: Relationship[]) => observableCombineLatest(relationships.map((relationship: Relationship) => this.getRelationshipTypeLabelByRelationshipAndItem(relationship, item)))),
map((labels: string[]) => Array.from(new Set(labels)))
);
@@ -212,7 +212,7 @@ export class RelationshipService extends DataService<Relationship> {
* @param item
*/
getRelatedItems(item: Item): Observable<Item[]> {
return this.getItemRelationshipsArray(item).pipe(
return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')).pipe(
relationsToItems(item.uuid)
);
}
@@ -225,17 +225,18 @@ export class RelationshipService extends DataService<Relationship> {
* @param options
*/
getRelatedItemsByLabel(item: Item, label: string, options?: FindListOptions): Observable<RemoteData<PaginatedList<Item>>> {
return this.getItemRelationshipsByLabel(item, label, options).pipe(paginatedRelationsToItems(item.uuid));
return this.getItemRelationshipsByLabel(item, label, options, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType')).pipe(paginatedRelationsToItems(item.uuid));
}
/**
* Resolve a given item's relationships into related items, filtered by a relationship label
* and return the items as an array
* Resolve a given item's relationships by label
* This should move to the REST API.
*
* @param item
* @param label
* @param options
*/
getItemRelationshipsByLabel(item: Item, label: string, options?: FindListOptions): Observable<RemoteData<PaginatedList<Relationship>>> {
getItemRelationshipsByLabel(item: Item, label: string, options?: FindListOptions, ...linksToFollow: Array<FollowLinkConfig<Relationship>>): Observable<RemoteData<PaginatedList<Relationship>>> {
let findListOptions = new FindListOptions();
if (options) {
findListOptions = Object.assign(new FindListOptions(), options);
@@ -246,7 +247,7 @@ export class RelationshipService extends DataService<Relationship> {
} else {
findListOptions.searchParams = searchParams;
}
return this.searchBy('byLabel', findListOptions, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType'));
return this.searchBy('byLabel', findListOptions, ...linksToFollow);
}
/**
@@ -256,7 +257,7 @@ export class RelationshipService extends DataService<Relationship> {
* @param uuids
*/
getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> {
return this.getItemRelationshipsArray(item).pipe(
return this.getItemRelationshipsArray(item, followLink('leftItem'), followLink('rightItem')).pipe(
switchMap((relationships: Relationship[]) => {
return observableCombineLatest(...relationships.map((relationship: Relationship) => {
const isLeftItem$ = this.isItemInUUIDArray(relationship.leftItem, uuids);

View File

@@ -5,7 +5,7 @@ import { RemoteData } from '../../data/remote-data';
import { HALLink } from '../hal-link.model';
import { RelationshipType } from './relationship-type.model';
import { Item } from '../item.model';
import { ITEM } from "../item-resource-type";
import { ITEM } from "../item.resource-type";
import { RELATIONSHIP } from "../relationship.resource-type";
/**

View File

@@ -12,7 +12,7 @@ import { DSpaceObject } from './dspace-object.model';
import { GenericConstructor } from './generic-constructor';
import { HALLink } from './hal-link.model';
import { Relationship } from './item-relationships/relationship.model';
import { ITEM } from "./item-resource-type";
import { ITEM } from "./item.resource-type";
import { RELATIONSHIP } from "./relationship.resource-type";
/**
@@ -50,13 +50,13 @@ export class Item extends DSpaceObject {
* The Collection that owns this Item
*/
@link(Collection.type)
owningCollection: Observable<RemoteData<Collection>>;
owningCollection?: Observable<RemoteData<Collection>>;
@link(Bundle.type, true)
bundles: Observable<RemoteData<PaginatedList<Bundle>>>;
bundles?: Observable<RemoteData<PaginatedList<Bundle>>>;
@link(RELATIONSHIP)
relationships: Observable<RemoteData<PaginatedList<Relationship>>>;
relationships?: Observable<RemoteData<PaginatedList<Relationship>>>;
_links: {
mappedCollections: HALLink;

View File

@@ -7,4 +7,3 @@ import { ResourceType } from "./resource-type";
* dependencies in webpack.
*/
export const RELATIONSHIP = new ResourceType('relationship');

View File

@@ -76,6 +76,7 @@ export function normalizeSectionData(obj: any, objIndex?: number) {
export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
protected toCache = false;
protected shouldDirectlyAttachEmbeds = true;
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
protected objectCache: ObjectCacheService,

View File

@@ -50,6 +50,7 @@ import {
DynamicNGBootstrapTimePickerComponent
} from '@ng-dynamic-forms/ui-ng-bootstrap';
import { TranslateService } from '@ngx-translate/core';
import { followLink } from '../../../utils/follow-link-config.model';
import {
Reorderable,
ReorderableRelationship
@@ -251,7 +252,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
this.subs.push(item$.subscribe((item) => this.item = item));
this.subs.push(collection$.subscribe((collection) => this.collection = collection));
this.reorderables$ = item$.pipe(
switchMap((item) => this.relationService.getItemRelationshipsByLabel(item, this.model.relationship.relationshipType)
switchMap((item) => this.relationService.getItemRelationshipsByLabel(item, this.model.relationship.relationshipType, undefined, followLink('leftItem'), followLink('rightItem'), followLink('relationshipType'))
.pipe(
getAllSucceededRemoteData(),
getRemoteDataPayload(),
@@ -285,7 +286,10 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
this.relationService.getRelatedItemsByLabel(this.item, this.model.relationship.relationshipType).pipe(
map((items: RemoteData<PaginatedList<Item>>) => items.payload.page.map((item) => Object.assign(new ItemSearchResult(), { indexableObject: item }))),
).subscribe((relatedItems: Array<SearchResult<Item>>) => this.selectableListService.select(this.listId, relatedItems));
).subscribe((relatedItems: Array<SearchResult<Item>>) => {
console.log('relatedItems', relatedItems);
this.selectableListService.select(this.listId, relatedItems)
});
}
}

View File

@@ -5,6 +5,7 @@ import { from as observableFrom, of as observableOf } from 'rxjs';
import { catchError, map, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { union } from 'lodash';
import { NormalizedSubmissionSectionModel } from '../../core/config/models/normalized-config-submission-section.model';
import {
CompleteInitSubmissionFormAction,
@@ -56,9 +57,10 @@ export class SubmissionObjectEffects {
map((action: InitSubmissionFormAction) => {
const definition = action.payload.submissionDefinition;
const mappedActions = [];
definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel) => {
const sectionId = sectionDefinition._links.self.href.substr(sectionDefinition._links.self.href.lastIndexOf('/') + 1);
const config = sectionDefinition._links.config.href || '';
definition.sections.page.forEach((sectionDefinition: any) => {
const selfLink = sectionDefinition._links.self.href || sectionDefinition._links.self;
const sectionId = selfLink.substr(selfLink.lastIndexOf('/') + 1);
const config = sectionDefinition._links.config ? (sectionDefinition._links.config.href || sectionDefinition._links.config) : '';
const enabled = (sectionDefinition.mandatory) || (isNotEmpty(action.payload.sections) && action.payload.sections.hasOwnProperty(sectionId));
const sectionData = (isNotUndefined(action.payload.sections) && isNotUndefined(action.payload.sections[sectionId])) ? action.payload.sections[sectionId] : Object.create(null);
const sectionErrors = null;