62849: intermediate commit, fixed issue with retrieving relationship type id

This commit is contained in:
lotte
2019-08-06 15:30:44 +02:00
parent 07d876348e
commit 28b450498f
18 changed files with 109 additions and 62 deletions

View File

@@ -213,9 +213,9 @@ describe('ItemMetadataComponent', () => {
}); });
it('it should call reinstateFieldUpdates on the objectUpdatesService with the correct url and metadata', () => { it('it should call reinstateFieldUpdates on the objectUpdatesService with the correct url and metadata', () => {
expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.item.metadataAsList); expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.itemRD$.metadataAsList);
expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.item, { metadata: Metadata.toMetadataMap(comp.item.metadataAsList) })); expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.itemRD$, { metadata: Metadata.toMetadataMap(comp.itemRD$.metadataAsList) }));
expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.item.metadataAsList); expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.itemRD$.metadataAsList);
}); });
}); });

View File

@@ -118,7 +118,7 @@ describe('EditRelationshipListComponent', () => {
fixture = TestBed.createComponent(EditRelationshipListComponent); fixture = TestBed.createComponent(EditRelationshipListComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
de = fixture.debugElement; de = fixture.debugElement;
comp.item = item; comp.itemRD$ = item;
comp.url = url; comp.url = url;
comp.relationshipLabel = relationshipType.leftLabel; comp.relationshipLabel = relationshipType.leftLabel;
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -114,7 +114,7 @@ describe('EditRelationshipComponent', () => {
comp.url = url; comp.url = url;
comp.fieldUpdate = fieldUpdate1; comp.fieldUpdate = fieldUpdate1;
comp.item = item; comp.itemRD$ = item;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -32,7 +32,7 @@ describe('ModifyItemOverviewComponent', () => {
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(ModifyItemOverviewComponent); fixture = TestBed.createComponent(ModifyItemOverviewComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItem; comp.itemRD$ = mockItem;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -31,7 +31,7 @@ describe('ItemPageAbstractFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageAbstractFieldComponent); fixture = TestBed.createComponent(ItemPageAbstractFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -32,7 +32,7 @@ describe('ItemPageAuthorFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageAuthorFieldComponent); fixture = TestBed.createComponent(ItemPageAuthorFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(field, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(field, mockValue);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -31,7 +31,7 @@ describe('ItemPageDateFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageDateFieldComponent); fixture = TestBed.createComponent(ItemPageDateFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -33,7 +33,7 @@ describe('GenericItemPageFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(GenericItemPageFieldComponent); fixture = TestBed.createComponent(GenericItemPageFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.fields = mockFields; comp.fields = mockFields;
comp.label = mockLabel; comp.label = mockLabel;
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -39,7 +39,7 @@ describe('ItemPageFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageFieldComponent); fixture = TestBed.createComponent(ItemPageFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
comp.fields = mockFields; comp.fields = mockFields;
comp.label = mockLabel; comp.label = mockLabel;
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -31,7 +31,7 @@ describe('ItemPageTitleFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageTitleFieldComponent); fixture = TestBed.createComponent(ItemPageTitleFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -31,7 +31,7 @@ describe('ItemPageUriFieldComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
fixture = TestBed.createComponent(ItemPageUriFieldComponent); fixture = TestBed.createComponent(ItemPageUriFieldComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.item = mockItemWithMetadataFieldAndValue(mockField, mockValue); comp.itemRD$ = mockItemWithMetadataFieldAndValue(mockField, mockValue);
fixture.detectChanges(); fixture.detectChanges();
})); }));

View File

@@ -29,7 +29,7 @@ describe('RelatedEntitiesSearchComponent', () => {
fixture = TestBed.createComponent(RelatedEntitiesSearchComponent); fixture = TestBed.createComponent(RelatedEntitiesSearchComponent);
comp = fixture.componentInstance; comp = fixture.componentInstance;
comp.relationType = mockRelationType; comp.relationType = mockRelationType;
comp.item = mockItem; comp.itemRD$ = mockItem;
comp.relationEntityType = mockRelationEntityType; comp.relationEntityType = mockRelationEntityType;
fixture.detectChanges(); fixture.detectChanges();
}); });

View File

@@ -2,29 +2,16 @@ import { Injectable } from '@angular/core';
import { RequestService } from './request.service'; import { RequestService } from './request.service';
import { HALEndpointService } from '../shared/hal-endpoint.service'; import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service'; import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util'; import { filter, find, map, switchMap } from 'rxjs/operators';
import { distinctUntilChanged, filter, flatMap, map, switchMap, take, tap } from 'rxjs/operators'; import { configureRequest, getSucceededRemoteData } from '../shared/operators';
import { import { FindAllOptions, FindAllRequest } from './request.models';
configureRequest,
filterSuccessfulResponses,
getRemoteDataPayload, getResponseFromEntry,
getSucceededRemoteData
} from '../shared/operators';
import { DeleteRequest, FindAllOptions, FindAllRequest, GetRequest, PostRequest, RestRequest } from './request.models';
import { Observable } from 'rxjs/internal/Observable'; import { Observable } from 'rxjs/internal/Observable';
import { RestResponse } from '../cache/response.models';
import { Item } from '../shared/item.model';
import { Relationship } from '../shared/item-relationships/relationship.model';
import { RelationshipType } from '../shared/item-relationships/relationship-type.model'; import { RelationshipType } from '../shared/item-relationships/relationship-type.model';
import { RemoteData } from './remote-data'; import { RemoteData } from './remote-data';
import { combineLatest as observableCombineLatest } from 'rxjs/internal/observable/combineLatest';
import { zip as observableZip } from 'rxjs';
import { PaginatedList } from './paginated-list'; import { PaginatedList } from './paginated-list';
import { ItemDataService } from './item-data.service'; import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs';
import { import { ItemType } from '../shared/item-relationships/item-type.model';
compareArraysUsingIds, filterRelationsByTypeLabel, import { isNotUndefined } from '../../shared/empty.util';
relationsToItems
} from '../../+item-page/simple/item-types/shared/item-relationships-utils';
/** /**
* The service handling all relationship requests * The service handling all relationship requests
@@ -62,13 +49,29 @@ export class RelationshipTypeService {
* Get the RelationshipType for a relationship type by label * Get the RelationshipType for a relationship type by label
* @param label * @param label
*/ */
getRelationshipTypeByLabel(label: string): Observable<RelationshipType> { getRelationshipTypeByLabelAndTypes(label: string, firstType: string, secondType: string): Observable<RelationshipType> {
return this.getAllRelationshipTypes({ currentPage: 1, elementsPerPage: Number.MAX_VALUE }).pipe( return this.getAllRelationshipTypes({ currentPage: 1, elementsPerPage: Number.MAX_VALUE })
map((typeListRD: RemoteData<PaginatedList<RelationshipType>>) => .pipe(
typeListRD.payload.page.find((type: RelationshipType) => getSucceededRemoteData(),
type.leftLabel === label || type.rightLabel === label /* Flatten the page so we can treat it like an observable */
) switchMap((typeListRD: RemoteData<PaginatedList<RelationshipType>>) => typeListRD.payload.page),
), switchMap((type: RelationshipType) => {
if (type.leftLabel === label) return this.checkType(type, firstType, secondType);
else if (type.rightLabel === label) return this.checkType(type, secondType, firstType);
else return [];
}),
);
}
// Check if relationship type matches the given types
// returns a void observable if there's not match
// returns an observable that emits the relationship type when there is a match
private checkType(type: RelationshipType, firstType: string, secondType: string): Observable<RelationshipType> {
const entityTypes = observableCombineLatest(type.leftType.pipe(getSucceededRemoteData()), type.rightType.pipe(getSucceededRemoteData()));
return entityTypes.pipe(
find(([leftTypeRD, rightTypeRD]: [RemoteData<ItemType>, RemoteData<ItemType>]) => leftTypeRD.payload.label === firstType && rightTypeRD.payload.label === secondType),
filter((types) => isNotUndefined(types)),
map(() => type)
); );
} }
} }

View File

@@ -10,6 +10,8 @@ export class ItemType implements CacheableObject {
*/ */
id: string; id: string;
label: string;
/** /**
* The link to the rest endpoint where this object can be found * The link to the rest endpoint where this object can be found
*/ */

View File

@@ -277,7 +277,7 @@ export class DsDynamicFormControlContainerComponent extends DynamicFormControlCo
modalComp.listId = this.listId; modalComp.listId = this.listId;
modalComp.relationship = this.model.relationship; modalComp.relationship = this.model.relationship;
modalComp.label = this.model.label; modalComp.label = this.model.label;
modalComp.item = this.model.workspaceItem.item; modalComp.itemRD$ = this.model.workspaceItem.item;
} }
removeSelection(object: SearchResult<DSpaceObject>) { removeSelection(object: SearchResult<DSpaceObject>) {

View File

@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnDestroy, OnInit } from '@angular/core';
import { PaginatedList } from '../../../../../core/data/paginated-list'; import { PaginatedList } from '../../../../../core/data/paginated-list';
import { SearchResult } from '../../../../search/search-result.model'; import { SearchResult } from '../../../../search/search-result.model';
import { RemoteData } from '../../../../../core/data/remote-data'; import { RemoteData } from '../../../../../core/data/remote-data';
@@ -24,7 +24,6 @@ import { RelationshipService } from '../../../../../core/data/relationship.servi
import { Item } from '../../../../../core/shared/item.model'; import { Item } from '../../../../../core/shared/item.model';
import { RelationshipOptions } from '../../models/relationship-options.model'; import { RelationshipOptions } from '../../models/relationship-options.model';
import { combineLatest as observableCombineLatest } from 'rxjs'; import { combineLatest as observableCombineLatest } from 'rxjs';
import { relationship } from '../../../../../core/cache/builders/build-decorators';
@Component({ @Component({
selector: 'ds-dynamic-lookup-relation-modal', selector: 'ds-dynamic-lookup-relation-modal',
@@ -37,10 +36,10 @@ import { relationship } from '../../../../../core/cache/builders/build-decorator
} }
] ]
}) })
export class DsDynamicLookupRelationModalComponent implements OnInit { export class DsDynamicLookupRelationModalComponent implements OnInit, OnDestroy {
label: string; label: string;
relationship: RelationshipOptions; relationship: RelationshipOptions;
item: Observable<RemoteData<Item>>; itemRD$: Observable<RemoteData<Item>>;
listId: string; listId: string;
resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<Item>>>>; resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<Item>>>>;
searchConfig: PaginatedSearchOptions; searchConfig: PaginatedSearchOptions;
@@ -49,12 +48,12 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
allSelected: boolean; allSelected: boolean;
someSelected$: Observable<boolean>; someSelected$: Observable<boolean>;
selectAllLoading: boolean; selectAllLoading: boolean;
subscription;
initialPagination = Object.assign(new PaginationComponentOptions(), { initialPagination = Object.assign(new PaginationComponentOptions(), {
id: 'submission-relation-list', id: 'submission-relation-list',
pageSize: 10 pageSize: 10
}); });
selection$: Observable<ListableObject[]>; selection$: Observable<ListableObject[]>;
relationshipType: Observable<RelationshipType>;
constructor( constructor(
public modal: NgbActiveModal, public modal: NgbActiveModal,
@@ -73,8 +72,6 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
this.routeService.setParameter('fixedFilterQuery', this.relationship.filter); this.routeService.setParameter('fixedFilterQuery', this.relationship.filter);
this.routeService.setParameter('configuration', this.relationship.searchConfiguration); this.routeService.setParameter('configuration', this.relationship.searchConfiguration);
this.relationshipType = this.relationshipTypeService.getRelationshipTypeByLabel(this.relationship.relationshipType);
this.selection$ = this.selectableListService.getSelectableList(this.listId).pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : [])); this.selection$ = this.selectableListService.getSelectableList(this.listId).pipe(map((listState: SelectableListState) => hasValue(listState) && hasValue(listState.selection) ? listState.selection : []));
this.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection))); this.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection)));
this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe( this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
@@ -149,15 +146,60 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
select(selectableObject: SearchResult<Item>) { select(selectableObject: SearchResult<Item>) {
observableCombineLatest(this.relationshipType, this.item).pipe(take(1)).subscribe( const relationshipType$: Observable<RelationshipType> = this.itemRD$.pipe(
([type, itemRD]: [RelationshipType, RemoteData<Item>]) => { getSucceededRemoteData(),
const isSwitched = type.rightLabel === this.relationship.relationshipType; switchMap((itemRD: RemoteData<Item>) => {
if (isSwitched) { const type1: string = itemRD.payload.firstMetadataValue('relationship.type');
this.relationshipService.addRelationship('1', selectableObject.indexableObject, itemRD.payload).pipe(getSucceededRemoteData()).subscribe(); const type2: string = selectableObject.indexableObject.firstMetadataValue('relationship.type');
} else { return this.relationshipTypeService.getRelationshipTypeByLabelAndTypes(this.relationship.relationshipType, type1, type2);
this.relationshipService.addRelationship('1', itemRD.payload, selectableObject.indexableObject).pipe(getSucceededRemoteData()).subscribe(); }));
}
} this.subscription = observableCombineLatest(relationshipType$, this.itemRD$)
) .pipe(
take(1),
switchMap(([type, itemRD]: [RelationshipType, RemoteData<Item>]) => {
const isSwitched = type.rightLabel === this.relationship.relationshipType;
let result;
if (isSwitched) {
result = this.relationshipService.addRelationship(type.id, selectableObject.indexableObject, itemRD.payload);
} else {
result = this.relationshipService.addRelationship(type.id, itemRD.payload, selectableObject.indexableObject);
}
console.log(result);
return result;
})
)
.subscribe();
}
deselect(selectableObject: SearchResult<Item>) {
const relationshipType$: Observable<RelationshipType> = this.itemRD$.pipe(
getSucceededRemoteData(),
switchMap((itemRD: RemoteData<Item>) => {
const type1: string = itemRD.payload.firstMetadataValue('relationship.type');
const type2: string = selectableObject.indexableObject.firstMetadataValue('relationship.type');
return this.relationshipTypeService.getRelationshipTypeByLabelAndTypes(this.relationship.relationshipType, type1, type2);
}));
this.subscription = observableCombineLatest(relationshipType$, this.itemRD$)
.pipe(
take(1),
switchMap(([type, itemRD]: [RelationshipType, RemoteData<Item>]) => {
const isSwitched = type.rightLabel === this.relationship.relationshipType;
if (isSwitched) {
return this.relationshipService.addRelationship(type.id, selectableObject.indexableObject, itemRD.payload);
} else {
return this.relationshipService.addRelationship(type.id, itemRD.payload, selectableObject.indexableObject);
}
})
)
.subscribe();
}
ngOnDestroy(): void {
if (hasValue(this.subscription)) {
this.subscription.unsubscribe();
}
} }
} }

View File

@@ -72,7 +72,7 @@ describe('ItemDetailPreviewComponent', () => {
fixture = TestBed.createComponent(ItemDetailPreviewComponent); fixture = TestBed.createComponent(ItemDetailPreviewComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
component.object = { hitHighlights: {} } as any; component.object = { hitHighlights: {} } as any;
component.item = mockItem; component.itemRD$ = mockItem;
component.separator = ', '; component.separator = ', ';
spyOn(component.item, 'getFiles').and.returnValue(mockItem.bitstreams); spyOn(component.item, 'getFiles').and.returnValue(mockItem.bitstreams);
fixture.detectChanges(); fixture.detectChanges();

View File

@@ -117,7 +117,7 @@ export function createMockApi() {
const id = req.params.item_id; const id = req.params.item_id;
try { try {
req.item_id = id; req.item_id = id;
req.item = ITEMS.items.find((item) => { req.itemRD$ = ITEMS.items.find((item) => {
return item.id === id; return item.id === id;
}); });
next(); next();
@@ -127,7 +127,7 @@ export function createMockApi() {
}); });
router.route('/items/:item_id').get((req, res) => { router.route('/items/:item_id').get((req, res) => {
res.json(toHALResponse(req, req.item)); res.json(toHALResponse(req, req.itemRD$));
}); });
router.route('/bundles').get((req, res) => { router.route('/bundles').get((req, res) => {