mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
fix links for relationships
This commit is contained in:
@@ -74,7 +74,7 @@ export const paginatedRelationsToItems = (thisId: string) =>
|
|||||||
source.pipe(
|
source.pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
switchMap((relationshipsRD: RemoteData<PaginatedList<Relationship>>) => {
|
switchMap((relationshipsRD: RemoteData<PaginatedList<Relationship>>) => {
|
||||||
return observableZip(
|
return observableCombineLatest(
|
||||||
...relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem))
|
...relationshipsRD.payload.page.map((rel: Relationship) => observableCombineLatest(rel.leftItem, rel.rightItem))
|
||||||
).pipe(
|
).pipe(
|
||||||
map((arr) =>
|
map((arr) =>
|
||||||
|
6
src/app/core/cache/builders/link.service.ts
vendored
6
src/app/core/cache/builders/link.service.ts
vendored
@@ -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>) {
|
public resolveLink<T extends HALResource>(model, linkToFollow: FollowLinkConfig<T>) {
|
||||||
const matchingLinkDef = getLinkDefinition(model.constructor, linkToFollow.name);
|
const matchingLinkDef = getLinkDefinition(model.constructor, linkToFollow.name);
|
||||||
|
|
||||||
|
@@ -227,9 +227,7 @@ export class RemoteDataBuildService {
|
|||||||
const domainModelConstructor = getMapsTo(normalized.constructor);
|
const domainModelConstructor = getMapsTo(normalized.constructor);
|
||||||
const domainModel = Object.assign(new domainModelConstructor(), normalized, halLinks);
|
const domainModel = Object.assign(new domainModelConstructor(), normalized, halLinks);
|
||||||
|
|
||||||
linksToFollow.forEach((linkToFollow: FollowLinkConfig<T>) => {
|
this.linkService.resolveLinks(domainModel, ...linksToFollow);
|
||||||
this.linkService.resolveLink(domainModel, linkToFollow);
|
|
||||||
});
|
|
||||||
|
|
||||||
return domainModel;
|
return domainModel;
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@ import { ObjectCacheService } from '../cache/object-cache.service';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
export class ConfigResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||||
protected toCache = false;
|
protected toCache = false;
|
||||||
|
protected shouldDirectlyAttachEmbeds = true;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||||
|
@@ -16,6 +16,7 @@ export abstract class BaseResponseParsingService {
|
|||||||
protected abstract EnvConfig: GlobalConfig;
|
protected abstract EnvConfig: GlobalConfig;
|
||||||
protected abstract objectCache: ObjectCacheService;
|
protected abstract objectCache: ObjectCacheService;
|
||||||
protected abstract toCache: boolean;
|
protected abstract toCache: boolean;
|
||||||
|
protected shouldDirectlyAttachEmbeds = false;
|
||||||
|
|
||||||
protected process<ObjectDomain>(data: any, request: RestRequest): any {
|
protected process<ObjectDomain>(data: any, request: RestRequest): any {
|
||||||
if (isNotEmpty(data)) {
|
if (isNotEmpty(data)) {
|
||||||
@@ -32,7 +33,17 @@ export abstract class BaseResponseParsingService {
|
|||||||
.keys(data._embedded)
|
.keys(data._embedded)
|
||||||
.filter((property) => data._embedded.hasOwnProperty(property))
|
.filter((property) => data._embedded.hasOwnProperty(property))
|
||||||
.forEach((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))
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,7 +9,6 @@ import { HALEndpointService } from '../shared/hal-endpoint.service';
|
|||||||
import { DataService } from './data.service';
|
import { DataService } from './data.service';
|
||||||
import { RemoteData } from './remote-data';
|
import { RemoteData } from './remote-data';
|
||||||
import { RequestService } from './request.service';
|
import { RequestService } from './request.service';
|
||||||
import { FindListOptions } from './request.models';
|
|
||||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
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 { dataService } from '../cache/builders/build-decorators';
|
||||||
import { MemoizedSelector, select, Store } from '@ngrx/store';
|
import { MemoizedSelector, select, Store } from '@ngrx/store';
|
||||||
import { combineLatest, combineLatest as observableCombineLatest } from 'rxjs';
|
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
|
* Get an item's relationships in the form of an array
|
||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
getItemRelationshipsArray(item: Item): Observable<Relationship[]> {
|
getItemRelationshipsArray(item: Item, ...linksToFollow: Array<FollowLinkConfig<Relationship>>): Observable<Relationship[]> {
|
||||||
return this.findAllByHref(item._links.relationships.href).pipe(
|
return this.findAllByHref(item._links.relationships.href, undefined, ...linksToFollow).pipe(
|
||||||
getSucceededRemoteData(),
|
getSucceededRemoteData(),
|
||||||
getRemoteDataPayload(),
|
getRemoteDataPayload(),
|
||||||
map((rels: PaginatedList<Relationship>) => rels.page),
|
map((rels: PaginatedList<Relationship>) => rels.page),
|
||||||
@@ -183,7 +183,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
getRelationshipTypeLabelsByItem(item: Item): Observable<string[]> {
|
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)))),
|
switchMap((relationships: Relationship[]) => observableCombineLatest(relationships.map((relationship: Relationship) => this.getRelationshipTypeLabelByRelationshipAndItem(relationship, item)))),
|
||||||
map((labels: string[]) => Array.from(new Set(labels)))
|
map((labels: string[]) => Array.from(new Set(labels)))
|
||||||
);
|
);
|
||||||
@@ -212,7 +212,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
* @param item
|
* @param item
|
||||||
*/
|
*/
|
||||||
getRelatedItems(item: Item): Observable<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)
|
relationsToItems(item.uuid)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -225,17 +225,18 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
* @param options
|
* @param options
|
||||||
*/
|
*/
|
||||||
getRelatedItemsByLabel(item: Item, label: string, options?: FindListOptions): Observable<RemoteData<PaginatedList<Item>>> {
|
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
|
* Resolve a given item's relationships by label
|
||||||
* and return the items as an array
|
* This should move to the REST API.
|
||||||
|
*
|
||||||
* @param item
|
* @param item
|
||||||
* @param label
|
* @param label
|
||||||
* @param options
|
* @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();
|
let findListOptions = new FindListOptions();
|
||||||
if (options) {
|
if (options) {
|
||||||
findListOptions = Object.assign(new FindListOptions(), options);
|
findListOptions = Object.assign(new FindListOptions(), options);
|
||||||
@@ -246,7 +247,7 @@ export class RelationshipService extends DataService<Relationship> {
|
|||||||
} else {
|
} else {
|
||||||
findListOptions.searchParams = searchParams;
|
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
|
* @param uuids
|
||||||
*/
|
*/
|
||||||
getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> {
|
getRelationshipsByRelatedItemIds(item: Item, uuids: string[]): Observable<Relationship[]> {
|
||||||
return this.getItemRelationshipsArray(item).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);
|
||||||
|
@@ -5,7 +5,7 @@ import { RemoteData } from '../../data/remote-data';
|
|||||||
import { HALLink } from '../hal-link.model';
|
import { HALLink } from '../hal-link.model';
|
||||||
import { RelationshipType } from './relationship-type.model';
|
import { RelationshipType } from './relationship-type.model';
|
||||||
import { Item } from '../item.model';
|
import { Item } from '../item.model';
|
||||||
import { ITEM } from "../item-resource-type";
|
import { ITEM } from "../item.resource-type";
|
||||||
import { RELATIONSHIP } from "../relationship.resource-type";
|
import { RELATIONSHIP } from "../relationship.resource-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -12,7 +12,7 @@ import { DSpaceObject } from './dspace-object.model';
|
|||||||
import { GenericConstructor } from './generic-constructor';
|
import { GenericConstructor } from './generic-constructor';
|
||||||
import { HALLink } from './hal-link.model';
|
import { HALLink } from './hal-link.model';
|
||||||
import { Relationship } from './item-relationships/relationship.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";
|
import { RELATIONSHIP } from "./relationship.resource-type";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,13 +50,13 @@ export class Item extends DSpaceObject {
|
|||||||
* The Collection that owns this Item
|
* The Collection that owns this Item
|
||||||
*/
|
*/
|
||||||
@link(Collection.type)
|
@link(Collection.type)
|
||||||
owningCollection: Observable<RemoteData<Collection>>;
|
owningCollection?: Observable<RemoteData<Collection>>;
|
||||||
|
|
||||||
@link(Bundle.type, true)
|
@link(Bundle.type, true)
|
||||||
bundles: Observable<RemoteData<PaginatedList<Bundle>>>;
|
bundles?: Observable<RemoteData<PaginatedList<Bundle>>>;
|
||||||
|
|
||||||
@link(RELATIONSHIP)
|
@link(RELATIONSHIP)
|
||||||
relationships: Observable<RemoteData<PaginatedList<Relationship>>>;
|
relationships?: Observable<RemoteData<PaginatedList<Relationship>>>;
|
||||||
|
|
||||||
_links: {
|
_links: {
|
||||||
mappedCollections: HALLink;
|
mappedCollections: HALLink;
|
||||||
|
@@ -7,4 +7,3 @@ import { ResourceType } from "./resource-type";
|
|||||||
* dependencies in webpack.
|
* dependencies in webpack.
|
||||||
*/
|
*/
|
||||||
export const RELATIONSHIP = new ResourceType('relationship');
|
export const RELATIONSHIP = new ResourceType('relationship');
|
||||||
|
|
||||||
|
@@ -76,6 +76,7 @@ export function normalizeSectionData(obj: any, objIndex?: number) {
|
|||||||
export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
export class SubmissionResponseParsingService extends BaseResponseParsingService implements ResponseParsingService {
|
||||||
|
|
||||||
protected toCache = false;
|
protected toCache = false;
|
||||||
|
protected shouldDirectlyAttachEmbeds = true;
|
||||||
|
|
||||||
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
constructor(@Inject(GLOBAL_CONFIG) protected EnvConfig: GlobalConfig,
|
||||||
protected objectCache: ObjectCacheService,
|
protected objectCache: ObjectCacheService,
|
||||||
|
@@ -50,6 +50,7 @@ import {
|
|||||||
DynamicNGBootstrapTimePickerComponent
|
DynamicNGBootstrapTimePickerComponent
|
||||||
} from '@ng-dynamic-forms/ui-ng-bootstrap';
|
} from '@ng-dynamic-forms/ui-ng-bootstrap';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { followLink } from '../../../utils/follow-link-config.model';
|
||||||
import {
|
import {
|
||||||
Reorderable,
|
Reorderable,
|
||||||
ReorderableRelationship
|
ReorderableRelationship
|
||||||
@@ -251,7 +252,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
this.subs.push(item$.subscribe((item) => this.item = item));
|
this.subs.push(item$.subscribe((item) => this.item = item));
|
||||||
this.subs.push(collection$.subscribe((collection) => this.collection = collection));
|
this.subs.push(collection$.subscribe((collection) => this.collection = collection));
|
||||||
this.reorderables$ = item$.pipe(
|
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(
|
.pipe(
|
||||||
getAllSucceededRemoteData(),
|
getAllSucceededRemoteData(),
|
||||||
getRemoteDataPayload(),
|
getRemoteDataPayload(),
|
||||||
@@ -285,7 +286,10 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
|
|||||||
|
|
||||||
this.relationService.getRelatedItemsByLabel(this.item, this.model.relationship.relationshipType).pipe(
|
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 }))),
|
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)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ import { from as observableFrom, of as observableOf } from 'rxjs';
|
|||||||
import { catchError, map, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
import { catchError, map, mergeMap, switchMap, tap, withLatestFrom } from 'rxjs/operators';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { union } from 'lodash';
|
import { union } from 'lodash';
|
||||||
|
import { NormalizedSubmissionSectionModel } from '../../core/config/models/normalized-config-submission-section.model';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CompleteInitSubmissionFormAction,
|
CompleteInitSubmissionFormAction,
|
||||||
@@ -56,9 +57,10 @@ export class SubmissionObjectEffects {
|
|||||||
map((action: InitSubmissionFormAction) => {
|
map((action: InitSubmissionFormAction) => {
|
||||||
const definition = action.payload.submissionDefinition;
|
const definition = action.payload.submissionDefinition;
|
||||||
const mappedActions = [];
|
const mappedActions = [];
|
||||||
definition.sections.page.forEach((sectionDefinition: SubmissionSectionModel) => {
|
definition.sections.page.forEach((sectionDefinition: any) => {
|
||||||
const sectionId = sectionDefinition._links.self.href.substr(sectionDefinition._links.self.href.lastIndexOf('/') + 1);
|
const selfLink = sectionDefinition._links.self.href || sectionDefinition._links.self;
|
||||||
const config = sectionDefinition._links.config.href || '';
|
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 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 sectionData = (isNotUndefined(action.payload.sections) && isNotUndefined(action.payload.sections[sectionId])) ? action.payload.sections[sectionId] : Object.create(null);
|
||||||
const sectionErrors = null;
|
const sectionErrors = null;
|
||||||
|
Reference in New Issue
Block a user