"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/app/item-page/edit-item-page/item-relationships/edit-relationship-list/edit-relationship-list.component.ts" between
dspace-angular-dspace-7.0.tar.gz and dspace-angular-dspace-7.1.tar.gz

About: dspace-angular is the Angular-based frontend of DSpace, a digital repository system to capture, store, index, preserve and redistribute an organization’s research material in digital formats.

edit-relationship-list.component.ts  (dspace-angular-dspace-7.0):edit-relationship-list.component.ts  (dspace-angular-dspace-7.1)
import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { Component, EventEmitter, Input, OnDestroy, OnInit, Output } from '@angu lar/core';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'; import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { LinkService } from '../../../../core/cache/builders/link.service'; import { LinkService } from '../../../../core/cache/builders/link.service';
import { FieldChangeType } from '../../../../core/data/object-updates/object-upd ates.actions'; import { FieldChangeType } from '../../../../core/data/object-updates/object-upd ates.actions';
import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec t-updates.service'; import { ObjectUpdatesService } from '../../../../core/data/object-updates/objec t-updates.service';
import { import { combineLatest as observableCombineLatest, from as observableFrom, Obser
combineLatest as observableCombineLatest, vable } from 'rxjs';
Observable,
of as observableOf,
from as observableFrom
} from 'rxjs';
import { import {
FieldUpdate, FieldUpdate,
FieldUpdates, FieldUpdates,
RelationshipIdentifiable RelationshipIdentifiable
} from '../../../../core/data/object-updates/object-updates.reducer'; } from '../../../../core/data/object-updates/object-updates.reducer';
import { RelationshipService } from '../../../../core/data/relationship.service' ; import { RelationshipService } from '../../../../core/data/relationship.service' ;
import { Item } from '../../../../core/shared/item.model'; import { Item } from '../../../../core/shared/item.model';
import { import { defaultIfEmpty, map, mergeMap, startWith, switchMap, take, tap, toArray
defaultIfEmpty, } from 'rxjs/operators';
map, import { hasNoValue, hasValue, hasValueOperator } from '../../../../shared/empty
mergeMap, .util';
switchMap,
take,
startWith,
toArray,
tap
} from 'rxjs/operators';
import { hasValue, hasValueOperator, hasNoValue } from '../../../../shared/empty
.util';
import { Relationship } from '../../../../core/shared/item-relationships/relatio nship.model'; import { Relationship } from '../../../../core/shared/item-relationships/relatio nship.model';
import { RelationshipType } from '../../../../core/shared/item-relationships/rel ationship-type.model'; import { RelationshipType } from '../../../../core/shared/item-relationships/rel ationship-type.model';
import { import {
getRemoteDataPayload, getAllSucceededRemoteData,
getFirstSucceededRemoteData, getFirstSucceededRemoteData,
getFirstSucceededRemoteDataPayload, getFirstSucceededRemoteDataPayload,
getAllSucceededRemoteData, getRemoteDataPayload,
} from '../../../../core/shared/operators'; } from '../../../../core/shared/operators';
import { ItemType } from '../../../../core/shared/item-relationships/item-type.m odel'; import { ItemType } from '../../../../core/shared/item-relationships/item-type.m odel';
import { DsDynamicLookupRelationModalComponent } from '../../../../shared/form/b uilder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.co mponent'; import { DsDynamicLookupRelationModalComponent } from '../../../../shared/form/b uilder/ds-dynamic-form-ui/relation-lookup-modal/dynamic-lookup-relation-modal.co mponent';
import { RelationshipOptions } from '../../../../shared/form/builder/models/rela tionship-options.model'; import { RelationshipOptions } from '../../../../shared/form/builder/models/rela tionship-options.model';
import { ItemSearchResult } from '../../../../shared/object-collection/shared/it em-search-result.model';
import { SelectableListService } from '../../../../shared/object-list/selectable -list/selectable-list.service'; import { SelectableListService } from '../../../../shared/object-list/selectable -list/selectable-list.service';
import { SearchResult } from '../../../../shared/search/search-result.model'; import { SearchResult } from '../../../../shared/search/search-result.model';
import { followLink } from '../../../../shared/utils/follow-link-config.model'; import { followLink } from '../../../../shared/utils/follow-link-config.model';
import { PaginatedList } from '../../../../core/data/paginated-list.model'; import { PaginatedList } from '../../../../core/data/paginated-list.model';
import { RemoteData } from '../../../../core/data/remote-data'; import { RemoteData } from '../../../../core/data/remote-data';
import { Collection } from '../../../../core/shared/collection.model'; import { Collection } from '../../../../core/shared/collection.model';
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject'; import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
import { Subscription } from 'rxjs/internal/Subscription'; import { Subscription } from 'rxjs/internal/Subscription';
import { PaginationComponentOptions } from '../../../../shared/pagination/pagina tion-component-options.model'; import { PaginationComponentOptions } from '../../../../shared/pagination/pagina tion-component-options.model';
import { PaginationService } from '../../../../core/pagination/pagination.servic e'; import { PaginationService } from '../../../../core/pagination/pagination.servic e';
import { RelationshipTypeService } from '../../../../core/data/relationship-type .service';
@Component({ @Component({
selector: 'ds-edit-relationship-list', selector: 'ds-edit-relationship-list',
styleUrls: ['./edit-relationship-list.component.scss'], styleUrls: ['./edit-relationship-list.component.scss'],
templateUrl: './edit-relationship-list.component.html', templateUrl: './edit-relationship-list.component.html',
}) })
/** /**
* A component creating a list of editable relationships of a certain type * A component creating a list of editable relationships of a certain type
* The relationships are rendered as a list of related items * The relationships are rendered as a list of related items
*/ */
skipping to change at line 83 skipping to change at line 69
* Used to fetch updates for the current item from the store * Used to fetch updates for the current item from the store
*/ */
@Input() url: string; @Input() url: string;
/** /**
* The label of the relationship-type we're rendering a list for * The label of the relationship-type we're rendering a list for
*/ */
@Input() relationshipType: RelationshipType; @Input() relationshipType: RelationshipType;
/** /**
* If updated information has changed
*/
@Input() hasChanges!: Observable<boolean>;
/**
* The event emmiter to submit the new information
*/
@Output() submit: EventEmitter<any> = new EventEmitter();
/**
* Observable that emits the left and right item type of {@link relationshipTy pe} simultaneously. * Observable that emits the left and right item type of {@link relationshipTy pe} simultaneously.
*/ */
private relationshipLeftAndRightType$: Observable<[ItemType, ItemType]>; private relationshipLeftAndRightType$: Observable<[ItemType, ItemType]>;
/** /**
* Observable that emits true if {@link itemType} is on the left-hand side of {@link relationshipType}, * Observable that emits true if {@link itemType} is on the left-hand side of {@link relationshipType},
* false if it is on the right-hand side and undefined in the rare case that i t is on neither side. * false if it is on the right-hand side and undefined in the rare case that i t is on neither side.
*/ */
private currentItemIsLeftItem$: Observable<boolean>; private currentItemIsLeftItem$: Observable<boolean>;
skipping to change at line 145 skipping to change at line 141
/** /**
* A reference to the lookup window * A reference to the lookup window
*/ */
modalRef: NgbModalRef; modalRef: NgbModalRef;
constructor( constructor(
protected objectUpdatesService: ObjectUpdatesService, protected objectUpdatesService: ObjectUpdatesService,
protected linkService: LinkService, protected linkService: LinkService,
protected relationshipService: RelationshipService, protected relationshipService: RelationshipService,
protected relationshipTypeService: RelationshipTypeService,
protected modalService: NgbModal, protected modalService: NgbModal,
protected paginationService: PaginationService, protected paginationService: PaginationService,
protected selectableListService: SelectableListService, protected selectableListService: SelectableListService,
) { ) {
} }
/** /**
* Get the i18n message key for this relationship type * Get the i18n message key for this relationship type
*/ */
public getRelationshipMessageKey(): Observable<string> { public getRelationshipMessageKey(): Observable<string> {
skipping to change at line 210 skipping to change at line 207
/** /**
* Open the dynamic lookup modal to search for items to add as relationships * Open the dynamic lookup modal to search for items to add as relationships
*/ */
openLookup() { openLookup() {
this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent , { this.modalRef = this.modalService.open(DsDynamicLookupRelationModalComponent , {
size: 'lg' size: 'lg'
}); });
const modalComp: DsDynamicLookupRelationModalComponent = this.modalRef.compo nentInstance; const modalComp: DsDynamicLookupRelationModalComponent = this.modalRef.compo nentInstance;
modalComp.repeatable = true; modalComp.repeatable = true;
modalComp.isEditRelationship = true;
modalComp.listId = this.listId; modalComp.listId = this.listId;
modalComp.item = this.item; modalComp.item = this.item;
modalComp.relationshipType = this.relationshipType;
modalComp.currentItemIsLeftItem$ = this.currentItemIsLeftItem$;
modalComp.toAdd = [];
modalComp.toRemove = [];
modalComp.isPending = false;
this.item.owningCollection.pipe( this.item.owningCollection.pipe(
getFirstSucceededRemoteDataPayload() getFirstSucceededRemoteDataPayload()
).subscribe((collection: Collection) => { ).subscribe((collection: Collection) => {
modalComp.collection = collection; modalComp.collection = collection;
}); });
modalComp.select = (...selectableObjects: SearchResult<Item>[]) => { modalComp.select = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => { selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject; const relatedItem: Item = searchResult.indexableObject;
this.getFieldUpdatesForRelatedItem(relatedItem)
.subscribe((identifiables) => { const foundIndex = modalComp.toRemove.findIndex( el => el.uuid === relat
identifiables.forEach((identifiable) => edItem.uuid);
this.objectUpdatesService.removeSingleFieldUpdate(this.url, identi
fiable.uuid) if (foundIndex !== -1) {
); modalComp.toRemove.splice(foundIndex,1);
if (identifiables.length === 0) { } else {
this.relationshipService.getNameVariant(this.listId, relatedItem.u
uid) this.getRelationFromId(relatedItem)
.subscribe((nameVariant) => { .subscribe((relationship: Relationship) => {
const update = { if (!relationship ) {
uuid: this.relationshipType.id + '-' + relatedItem.uuid, modalComp.toAdd.push(searchResult);
nameVariant, } else {
type: this.relationshipType, const foundIndexRemove = modalComp.toRemove.findIndex( el => el.
relatedItem, indexableObject.uuid === relatedItem.uuid);
} as RelationshipIdentifiable; if (foundIndexRemove !== -1) {
this.objectUpdatesService.saveAddFieldUpdate(this.url, update) modalComp.toRemove.splice(foundIndexRemove,1);
; }
}); }
}
this.loading$.next(true);
this.loading$.next(true); // emit the last page again to trigger a fieldupdates refresh
// emit the last page again to trigger a fieldupdates refresh this.relationshipsRd$.next(this.relationshipsRd$.getValue());
this.relationshipsRd$.next(this.relationshipsRd$.getValue()); });
}); }
}); });
}; };
modalComp.deselect = (...selectableObjects: SearchResult<Item>[]) => { modalComp.deselect = (...selectableObjects: SearchResult<Item>[]) => {
selectableObjects.forEach((searchResult) => { selectableObjects.forEach((searchResult) => {
const relatedItem: Item = searchResult.indexableObject; const relatedItem: Item = searchResult.indexableObject;
this.objectUpdatesService.removeSingleFieldUpdate(this.url, this.relatio
nshipType.id + '-' + relatedItem.uuid); const foundIndex = modalComp.toAdd.findIndex( el => el.indexableObject.u
this.getFieldUpdatesForRelatedItem(relatedItem) uid === relatedItem.uuid);
.subscribe((identifiables) =>
identifiables.forEach((identifiable) => if (foundIndex !== -1) {
this.objectUpdatesService.saveRemoveFieldUpdate(this.url, identifi modalComp.toAdd.splice(foundIndex,1);
able) } else {
) modalComp.toRemove.push(searchResult);
); }
});
};
modalComp.submitEv = () => {
const subscriptions = [];
modalComp.toAdd.forEach((searchResult: SearchResult<Item>) => {
const relatedItem = searchResult.indexableObject;
subscriptions.push(this.relationshipService.getNameVariant(this.listId,
relatedItem.uuid).pipe(
map((nameVariant) => {
const update = {
uuid: this.relationshipType.id + '-' + searchResult.indexableObject.
uuid,
nameVariant,
type: this.relationshipType,
relatedItem,
} as RelationshipIdentifiable;
this.objectUpdatesService.saveAddFieldUpdate(this.url, update);
return update;
})
));
});
modalComp.toRemove.forEach( (searchResult) => {
subscriptions.push(this.relationshipService.getNameVariant(this.listId,
searchResult.indexableObjectuuid).pipe(
switchMap((nameVariant) => {
return this.getRelationFromId(searchResult.indexableObject).pipe(
map( (relationship: Relationship) => {
const update = {
uuid: relationship.id,
nameVariant,
type: this.relationshipType,
relationship,
} as RelationshipIdentifiable;
this.objectUpdatesService.saveRemoveFieldUpdate(this.url,update)
;
return update;
})
);
})
));
});
observableCombineLatest(subscriptions).subscribe( (res) => {
// Wait until the states changes since there are multiple items
setTimeout( () => {
this.submit.emit();
},1000);
modalComp.isPending = true;
});
};
modalComp.discardEv = () => {
modalComp.toAdd.forEach( (searchResult) => {
this.selectableListService.deselectSingle(this.listId,searchResult);
});
modalComp.toRemove.forEach( (searchResult) => {
this.selectableListService.selectSingle(this.listId,searchResult);
}); });
this.loading$.next(true); modalComp.toAdd = [];
// emit the last page again to trigger a fieldupdates refresh modalComp.toRemove = [];
this.relationshipsRd$.next(this.relationshipsRd$.getValue());
}; };
this.relatedEntityType$ this.relatedEntityType$
.pipe(take(1)) .pipe(take(1))
.subscribe((relatedEntityType) => { .subscribe((relatedEntityType) => {
modalComp.relationshipOptions = Object.assign( modalComp.relationshipOptions = Object.assign(
new RelationshipOptions(), { new RelationshipOptions(), {
relationshipType: relatedEntityType.label, relationshipType: relatedEntityType.label,
// filter: this.getRelationshipMessageKey(),
searchConfiguration: relatedEntityType.label.toLowerCase(), searchConfiguration: relatedEntityType.label.toLowerCase(),
nameVariants: true, nameVariants: 'true',
} }
); );
}); });
this.selectableListService.deselectAll(this.listId); this.selectableListService.deselectAll(this.listId);
this.updates$.pipe( }
switchMap((updates) =>
Object.values(updates).length > 0 ? getRelationFromId(relatedItem) {
observableCombineLatest( return this.currentItemIsLeftItem$.pipe(
Object.values(updates)
.filter((update) => update.changeType !== FieldChangeType.REMOVE)
.map((update) => {
const field = update.field as RelationshipIdentifiable;
if (field.relationship) {
return this.getRelatedItem(field.relationship);
} else {
return observableOf(field.relatedItem);
}
})
) : observableOf([])
),
take(1), take(1),
map((items) => items.map((item) => { switchMap( isLeft => {
const searchResult = new ItemSearchResult(); let apiCall;
searchResult.indexableObject = item; if (isLeft) {
searchResult.hitHighlights = {}; apiCall = this.relationshipService.searchByItemsAndType( this.relation
return searchResult; shipType.id, this.item.uuid, this.relationshipType.leftwardType ,[relatedItem.id
})), ] ).pipe(
).subscribe((items) => { getFirstSucceededRemoteData(),
this.selectableListService.select(this.listId, items); getRemoteDataPayload(),
}); );
} else {
apiCall = this.relationshipService.searchByItemsAndType( this.relation
shipType.id, this.item.uuid, this.relationshipType.rightwardType ,[relatedItem.i
d] ).pipe(
getFirstSucceededRemoteData(),
getRemoteDataPayload(),
);
}
return apiCall.pipe(
map( (res: PaginatedList<Relationship>) => res.page[0])
);
}
));
} }
/** /**
* Get the existing field updates regarding a relationship with a given item * Get the existing field updates regarding a relationship with a given item
* @param relatedItem The item for which to get the existing field updates * @param relatedItem The item for which to get the existing field updates
*/ */
private getFieldUpdatesForRelatedItem(relatedItem: Item): Observable<Relations hipIdentifiable[]> { private getFieldUpdatesForRelatedItem(relatedItem: Item): Observable<Relations hipIdentifiable[]> {
return this.updates$.pipe( return this.updates$.pipe(
take(1), take(1),
map((updates) => Object.values(updates) map((updates) => Object.values(updates)
.map((update) => update.field as RelationshipIdentifiable) .map((update) => update.field as RelationshipIdentifiable)
.filter((field) => field.relationship) .filter((field) => field.relationship)
), ),
mergeMap((identifiables) => mergeMap((identifiables) =>
observableCombineLatest( observableCombineLatest(
identifiables.map((identifiable) => this.getRelatedItem(identifiable.r elationship)) identifiables.map((identifiable) => this.getRelatedItem(identifiable.r elationship))
).pipe( ).pipe(
defaultIfEmpty([]), defaultIfEmpty([]),
map((relatedItems) => map((relatedItems) => {
identifiables.filter((identifiable, index) => relatedItems[index].uu return identifiables.filter( (identifiable, index) => {
id === relatedItem.uuid) return relatedItems[index].uuid === relatedItem.uuid;
});
}
), ),
) )
), )
);
}
/**
* Check if the given item is related with the item we are editing relationshi
ps
* @param relatedItem The item for which to get the existing field updates
*/
private getIsRelatedItem(relatedItem: Item): Observable<boolean> {
return this.currentItemIsLeftItem$.pipe(
take(1),
map( isLeft => {
if (isLeft) {
const listOfRelatedItems = this.item.allMetadataValues( 'relation.' +
this.relationshipType.leftwardType );
return !!listOfRelatedItems.find( (uuid) => uuid === relatedItem.uuid
);
} else {
const listOfRelatedItems = this.item.allMetadataValues( 'relation.' +
this.relationshipType.rightwardType );
return !!listOfRelatedItems.find( (uuid) => uuid === relatedItem.uuid
);
}
})
); );
} }
/** /**
* Get the related item for a given relationship * Get the related item for a given relationship
* @param relationship The relationship for which to get the related item * @param relationship The relationship for which to get the related item
*/ */
private getRelatedItem(relationship: Relationship): Observable<Item> { private getRelatedItem(relationship: Relationship): Observable<Item> {
return this.relationshipService.isLeftItem(relationship, this.item).pipe( return this.relationshipService.isLeftItem(relationship, this.item).pipe(
switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationsh ip.leftItem), switchMap((isLeftItem) => isLeftItem ? relationship.rightItem : relationsh ip.leftItem),
getFirstSucceededRemoteData(), getFirstSucceededRemoteData(),
getRemoteDataPayload(), getRemoteDataPayload(),
) as Observable<Item>; ) as Observable<Item>;
} }
ngOnInit(): void { ngOnInit(): void {
// store the left and right type of the relationship in a single observable // store the left and right type of the relationship in a single observable
this.relationshipLeftAndRightType$ = observableCombineLatest([ this.relationshipLeftAndRightType$ = observableCombineLatest([
this.relationshipType.leftType, this.relationshipType.leftType,
this.relationshipType.rightType, this.relationshipType.rightType,
].map((type) => type.pipe( ].map((type) => type.pipe(
getFirstSucceededRemoteData(), getFirstSucceededRemoteData(),
getRemoteDataPayload(), getRemoteDataPayload(),
))) as Observable<[ItemType, ItemType]>; ))) as Observable<[ItemType, ItemType]>;
this.relatedEntityType$ = this.relationshipLeftAndRightType$.pipe( this.relatedEntityType$ = this.relationshipLeftAndRightType$.pipe(
 End of changes. 24 change blocks. 
91 lines changed or deleted 189 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)