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', () => {
expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.item.metadataAsList);
expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.item, { metadata: Metadata.toMetadataMap(comp.item.metadataAsList) }));
expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.item.metadataAsList);
expect(objectUpdatesService.getUpdatedFields).toHaveBeenCalledWith(url, comp.itemRD$.metadataAsList);
expect(itemService.update).toHaveBeenCalledWith(Object.assign(comp.itemRD$, { metadata: Metadata.toMetadataMap(comp.itemRD$.metadataAsList) }));
expect(objectUpdatesService.getFieldUpdates).toHaveBeenCalledWith(url, comp.itemRD$.metadataAsList);
});
});

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -2,29 +2,16 @@ import { Injectable } from '@angular/core';
import { RequestService } from './request.service';
import { HALEndpointService } from '../shared/hal-endpoint.service';
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
import { hasValue, hasValueOperator, isNotEmptyOperator } from '../../shared/empty.util';
import { distinctUntilChanged, filter, flatMap, map, switchMap, take, tap } from 'rxjs/operators';
import {
configureRequest,
filterSuccessfulResponses,
getRemoteDataPayload, getResponseFromEntry,
getSucceededRemoteData
} from '../shared/operators';
import { DeleteRequest, FindAllOptions, FindAllRequest, GetRequest, PostRequest, RestRequest } from './request.models';
import { filter, find, map, switchMap } from 'rxjs/operators';
import { configureRequest, getSucceededRemoteData } from '../shared/operators';
import { FindAllOptions, FindAllRequest } from './request.models';
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 { 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 { ItemDataService } from './item-data.service';
import {
compareArraysUsingIds, filterRelationsByTypeLabel,
relationsToItems
} from '../../+item-page/simple/item-types/shared/item-relationships-utils';
import { of as observableOf, combineLatest as observableCombineLatest } from 'rxjs';
import { ItemType } from '../shared/item-relationships/item-type.model';
import { isNotUndefined } from '../../shared/empty.util';
/**
* The service handling all relationship requests
@@ -62,13 +49,29 @@ export class RelationshipTypeService {
* Get the RelationshipType for a relationship type by label
* @param label
*/
getRelationshipTypeByLabel(label: string): Observable<RelationshipType> {
return this.getAllRelationshipTypes({ currentPage: 1, elementsPerPage: Number.MAX_VALUE }).pipe(
map((typeListRD: RemoteData<PaginatedList<RelationshipType>>) =>
typeListRD.payload.page.find((type: RelationshipType) =>
type.leftLabel === label || type.rightLabel === label
)
),
getRelationshipTypeByLabelAndTypes(label: string, firstType: string, secondType: string): Observable<RelationshipType> {
return this.getAllRelationshipTypes({ currentPage: 1, elementsPerPage: Number.MAX_VALUE })
.pipe(
getSucceededRemoteData(),
/* 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;
label: string;
/**
* 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.relationship = this.model.relationship;
modalComp.label = this.model.label;
modalComp.item = this.model.workspaceItem.item;
modalComp.itemRD$ = this.model.workspaceItem.item;
}
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 { SearchResult } from '../../../../search/search-result.model';
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 { RelationshipOptions } from '../../models/relationship-options.model';
import { combineLatest as observableCombineLatest } from 'rxjs';
import { relationship } from '../../../../../core/cache/builders/build-decorators';
@Component({
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;
relationship: RelationshipOptions;
item: Observable<RemoteData<Item>>;
itemRD$: Observable<RemoteData<Item>>;
listId: string;
resultsRD$: Observable<RemoteData<PaginatedList<SearchResult<Item>>>>;
searchConfig: PaginatedSearchOptions;
@@ -49,12 +48,12 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
allSelected: boolean;
someSelected$: Observable<boolean>;
selectAllLoading: boolean;
subscription;
initialPagination = Object.assign(new PaginationComponentOptions(), {
id: 'submission-relation-list',
pageSize: 10
});
selection$: Observable<ListableObject[]>;
relationshipType: Observable<RelationshipType>;
constructor(
public modal: NgbActiveModal,
@@ -73,8 +72,6 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
this.routeService.setParameter('fixedFilterQuery', this.relationship.filter);
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.someSelected$ = this.selection$.pipe(map((selection) => isNotEmpty(selection)));
this.resultsRD$ = this.searchConfigService.paginatedSearchOptions.pipe(
@@ -149,15 +146,60 @@ export class DsDynamicLookupRelationModalComponent implements OnInit {
select(selectableObject: SearchResult<Item>) {
observableCombineLatest(this.relationshipType, this.item).pipe(take(1)).subscribe(
([type, itemRD]: [RelationshipType, RemoteData<Item>]) => {
const isSwitched = type.rightLabel === this.relationship.relationshipType;
if (isSwitched) {
this.relationshipService.addRelationship('1', selectableObject.indexableObject, itemRD.payload).pipe(getSucceededRemoteData()).subscribe();
} else {
this.relationshipService.addRelationship('1', itemRD.payload, selectableObject.indexableObject).pipe(getSucceededRemoteData()).subscribe();
}
}
)
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;
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);
component = fixture.componentInstance;
component.object = { hitHighlights: {} } as any;
component.item = mockItem;
component.itemRD$ = mockItem;
component.separator = ', ';
spyOn(component.item, 'getFiles').and.returnValue(mockItem.bitstreams);
fixture.detectChanges();

View File

@@ -117,7 +117,7 @@ export function createMockApi() {
const id = req.params.item_id;
try {
req.item_id = id;
req.item = ITEMS.items.find((item) => {
req.itemRD$ = ITEMS.items.find((item) => {
return item.id === id;
});
next();
@@ -127,7 +127,7 @@ export function createMockApi() {
});
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) => {